twpayne/chezmoi · error
expected a []string, got a %T element
Error message
expected a []string, got a %T element
What it means
Same decode hook as the array-level check, but this fires per element: the data was a []any, yet one of its elements is not a string. The error reports the element's actual Go type so the offending config value can be identified.
Source
Thrown at internal/chezmoi/entrytypeset.go:361
}
// StringSliceToEntryTypeSetHookFunc is a
// github.com/go-viper/mapstructure/v2.DecodeHookFunc that parses an
// EntryTypeSet from a []string.
func StringSliceToEntryTypeSetHookFunc() mapstructure.DecodeHookFunc {
return func(from, to reflect.Type, data any) (any, error) {
if to != reflect.TypeFor[EntryTypeSet]() {
return data, nil
}
elemsAny, ok := data.([]any)
if !ok {
return nil, fmt.Errorf("expected a []string, got a %T", data)
}
elemStrs := make([]string, len(elemsAny))
for i, elemAny := range elemsAny {
elemStr, ok := elemAny.(string)
if !ok {
return nil, fmt.Errorf("expected a []string, got a %T element", elemAny)
}
elemStrs[i] = elemStr
}
s := NewEntryTypeSet(EntryTypesNone)
if err := s.SetSlice(elemStrs); err != nil {
return nil, err
}
return s, nil
}
}
// EntryTypeSetFlagCompletionFunc completes EntryTypeSet flags.
func EntryTypeSetFlagCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var completions []string
entryTypes := strings.Split(toComplete, ",")
lastEntryType := entryTypes[len(entryTypes)-1]
var prefix string
if len(entryTypes) > 0 {View on GitHub (pinned to f901167e46)
Solutions
- Quote the element so it parses as a string (e.g. ["file"] not [file] where file resolves oddly)
- Flatten accidental nested lists
- Inspect the reported %T type to locate the bad element and correct it
Example fix
// before mode = [file, dir] // after mode = ["file", "dir"]
Defensive patterns
Strategy: type-guard
Validate before calling
for i, e := range elems {
if _, ok := e.(string); !ok {
return fmt.Errorf("element %d is %T, want string", i, e)
}
} Type guard
func isStringElem(v any) bool {
_, ok := v.(string)
return ok
} Try / catch
if err := decode(data, &out); err != nil {
if strings.Contains(err.Error(), "got a %T element") || strings.Contains(err.Error(), " element") {
// coerce numeric/bool elements to strings and retry
}
} Prevention
- Quote list elements in config so parsers yield strings
- Avoid nested lists in entry-type fields
- Run config through a linter/schema check before feeding to decode hooks
When it happens
Trigger: An entry type list contains a non-string element, e.g. mode = [123], [true], or a nested list [["file"]] resulting from YAML/JSON parsing.
Common situations: Unquoted numeric-looking type values in TOML/YAML, accidental nesting of lists, template or script generating config with wrong element types.
Related errors
- expected a []string, got a %T
- expected a string, got a %T
- %s: unknown compression format
- %s: unknown format
- %s: %w
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/1f74737e58bdfcb8.
Report an issue: GitHub.