{"record":{"id":"ed9098126097f79e","repo":"twpayne/chezmoi","slug":"expected-a-string-got-a-t","errorCode":null,"errorMessage":"expected a string, got a %T","messagePattern":"expected a string, got a %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/chezmoi/abspath.go","lineNumber":188,"sourceCode":"\t}\n\tabsPath, err := NormalizePath(userHomeDir)\n\tif err != nil {\n\t\treturn EmptyAbsPath, err\n\t}\n\treturn absPath, nil\n}\n\n// StringToAbsPathHookFunc is a\n// github.com/go-viper/mapstructure/v2.DecodeHookFunc that parses an AbsPath\n// from a string.\nfunc StringToAbsPathHookFunc() mapstructure.DecodeHookFunc {\n\treturn func(from, to reflect.Type, data any) (any, error) {\n\t\tif to != reflect.TypeFor[AbsPath]() {\n\t\t\treturn data, nil\n\t\t}\n\t\ts, ok := data.(string)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"expected a string, got a %T\", data)\n\t\t}\n\t\tvar absPath AbsPath\n\t\tif err := absPath.Set(s); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn absPath, nil\n\t}\n}\n","sourceCodeStart":170,"sourceCodeEnd":197,"githubUrl":"https://github.com/twpayne/chezmoi/blob/f901167e4685db90da56d6a2a19df642cb3e0247/internal/chezmoi/abspath.go#L170-L197","documentation":"This error comes from a mapstructure DecodeHook (internal/chezmoi/abspath.go:188) that converts string config values into AbsPath. It fires when the input data to be decoded is not a string (e.g. a bool, int, or map) so the hook cannot run AbsPath.Set on it.","triggerScenarios":"Decoding chezmoi config data where a field expecting a path string (e.g. sourceDir, destDir, data file paths) contains a non-string value like a number or boolean in YAML/JSON/TOML.","commonSituations":"Quoting mistakes in config files: a path written as true/null or a numeric value assigned to a *_dir key; templated config emitting a non-string type.","solutions":["Quote the path value in your config file so it parses as a string.","Check the specific field named in the decode error and fix its type.","If using templates, ensure the template output renders as a string (use printf %q or quotes)."],"exampleFix":"# before\nsourceDir: 1234\n# after\nsourceDir: \"/home/user/.local/share/chezmoi\"","handlingStrategy":"validation","validationCode":"v, ok := raw.(string)\nif !ok {\n    return fmt.Errorf(\"path field must be a string, got %T\", raw)\n}","typeGuard":"func isString(v any) bool { _, ok := v.(string); return ok }","tryCatchPattern":"var cfg Config\nif err := mapstructure.Decode(raw, &cfg, decodeHooks...); err != nil {\n    if strings.Contains(err.Error(), \"expected a string\") {\n        // report which config key held a non-string\n    }\n    return err\n}","preventionTips":["Quote all path values in YAML/TOML config files.","Ensure template-rendered configs emit strings for path fields.","Validate config with `chezmoi doctor` or a dry-run apply."],"tags":["configuration","type-mismatch","decode-hook","path"],"backgroundTag":"type-mismatch","analyzedSha":"f901167e4685db90da56d6a2a19df642cb3e0247","analyzedAt":"2026-09-01T18:16:41.508Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}