twpayne/chezmoi · error

expected a string, got a %T

Error message

expected a string, got a %T

What it means

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.

Source

Thrown at internal/chezmoi/abspath.go:188

	}
	absPath, err := NormalizePath(userHomeDir)
	if err != nil {
		return EmptyAbsPath, err
	}
	return absPath, nil
}

// StringToAbsPathHookFunc is a
// github.com/go-viper/mapstructure/v2.DecodeHookFunc that parses an AbsPath
// from a string.
func StringToAbsPathHookFunc() mapstructure.DecodeHookFunc {
	return func(from, to reflect.Type, data any) (any, error) {
		if to != reflect.TypeFor[AbsPath]() {
			return data, nil
		}
		s, ok := data.(string)
		if !ok {
			return nil, fmt.Errorf("expected a string, got a %T", data)
		}
		var absPath AbsPath
		if err := absPath.Set(s); err != nil {
			return nil, err
		}
		return absPath, nil
	}
}

View on GitHub (pinned to f901167e46)

Solutions

  1. Quote the path value in your config file so it parses as a string.
  2. Check the specific field named in the decode error and fix its type.
  3. If using templates, ensure the template output renders as a string (use printf %q or quotes).

Example fix

# before
sourceDir: 1234
# after
sourceDir: "/home/user/.local/share/chezmoi"
Defensive patterns

Strategy: validation

Validate before calling

v, ok := raw.(string)
if !ok {
    return fmt.Errorf("path field must be a string, got %T", raw)
}

Type guard

func isString(v any) bool { _, ok := v.(string); return ok }

Try / catch

var cfg Config
if err := mapstructure.Decode(raw, &cfg, decodeHooks...); err != nil {
    if strings.Contains(err.Error(), "expected a string") {
        // report which config key held a non-string
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01). Data as JSON: /api/errors/ed9098126097f79e. Report an issue: GitHub.