twpayne/chezmoi · error
%s: %w
Error message
%s: %w
What it means
FormatFromAbsPath determines the Format for a file from its extension via formatFromExtension and wraps any failure with the full absolute path for context. The underlying cause is almost always the 'unknown format' error from the extension lookup, so the final message reads '<path>: <ext>: unknown format'.
Source
Thrown at internal/chezmoi/format.go:196
decoder := yaml.NewDecoder(
bytes.NewReader(data),
yaml.DisallowUnknownField(),
)
switch err := decoder.Decode(value); {
case errors.Is(err, io.EOF):
return nil // Empty input is OK.
case err != nil:
return err
default:
return nil
}
}
// FormatFromAbsPath returns the expected format of absPath.
func FormatFromAbsPath(absPath AbsPath) (Format, error) {
format, err := formatFromExtension(absPath.Ext())
if err != nil {
return nil, fmt.Errorf("%s: %w", absPath, err)
}
return format, nil
}
// formatFromExtension returns the expected format of absPath.
func formatFromExtension(extension string) (Format, error) {
format, ok := FormatsByExtension[strings.TrimPrefix(extension, ".")]
if !ok {
return nil, fmt.Errorf("%s: unknown format", extension)
}
return format, nil
}
func isPrefixDotFormat(name, prefix string) bool {
for extension := range FormatsByExtension {
if name == prefix+"."+extension {
return true
}View on GitHub (pinned to f901167e46)
Solutions
- Use a supported extension for the file (.json/.jsonc/.yaml/.yml/.toml)
- Specify the format explicitly where the API allows instead of relying on extension inference
- Correct the path passed to FormatFromAbsPath if it points at the wrong file
Example fix
// before
format, err := chezmoi.FormatFromAbsPath(chezmoi.NewAbsPath("/home/u/.secrets.txt"))
// after
format, err := chezmoi.FormatFromAbsPath(chezmoi.NewAbsPath("/home/u/.secrets.yaml")) Defensive patterns
Strategy: validation
Validate before calling
ext := strings.TrimPrefix(filepath.Ext(absPath.String()), ".")
switch ext {
case "json", "jsonc", "yaml", "yml", "toml":
// ok
default:
return fmt.Errorf("%s has unsupported format extension", absPath)
} Try / catch
format, err := chezmoi.FormatFromAbsPath(p)
if err != nil {
// err is wrapped; check for 'unknown format' inside and choose a default
return fmt.Errorf("cannot infer format: %w", err)
} Prevention
- Verify file extensions before calling format inference APIs
- Use explicit format parameters where available
- Standardize on lowercase canonical extensions in tooling
When it happens
Trigger: Calling FormatFromAbsPath (from addExternal, addTemplateData, decodeConfigFile, persistentPostRunRootE) with a file whose extension is not registered in FormatsByExtension.
Common situations: chezmoi add or chezmoi init on a file with a non-format extension, a config file path typo'd extension, archive/external files with exotic extensions.
Related errors
- %s: unknown format
- %s: unknown compression format
- expected a []string, got a %T
- expected a []string, got a %T element
- encryption not configured
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/e23b45466c12f40c.
Report an issue: GitHub.