Skip to content

fix: do not report a field tagged "-" as unset - #218

Open
herniqeu wants to merge 3 commits into
go-viper:mainfrom
herniqeu:fix/ignore-dash-tag
Open

herniqeu wants to merge 3 commits into
go-viper:mainfrom
herniqeu:fix/ignore-dash-tag

Conversation

@herniqeu

@herniqeu herniqeu commented Nov 1, 2026

Copy link
Copy Markdown

With ErrorUnset enabled, a field tagged mapstructure:"-" makes the decode fail with a message that names the dash as a missing field:

type config struct {
	A string `mapstructure:"a"`
	B string `mapstructure:"-"` // explicitly ignored
}

var out config
decoder, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
	ErrorUnset: true,
	Result:     &out,
})
err := decoder.Decode(map[string]any{"a": "x"})
// decoding failed due to the following error(s):
//     '' has unset fields: -

The tag means "do not decode this field", so it cannot also mean "this field is missing from the input". IgnoreUntaggedFields does not help, because the field is tagged. The workaround in #89 is to post-process Metadata.Unset and drop every name ending in -, which is what a config library ends up doing for its users (viper.Unmarshal).

The fields collection in decodeStructFromMap visits the ignored field and, since the tag becomes its key, looks for a key named - in the input, does not find it, and records it as unset. The fix skips fields whose first tag part is - while the field list is built, so they are neither decoded nor reported. Fields with a real tag keep failing as before, and the test for that stays in place.

Tests in unset_dash_test.go: the ignored field no longer fails ErrorUnset and does not appear in Metadata.Unset, while a genuinely missing field still returns the error naming it. Both fail on main and pass with the change; go test ./... passes.

Fixes #89.

Written with AI assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ErrorUnset conflicts with UntaggedFields

1 participant