twpayne/chezmoi · error
%s: unknown format
Error message
%s: unknown format
What it means
UnmarshalFileData guesses the serialization format from the file's extension (via FormatsByExtension) and unmarshals accordingly. If the extension has no registered format (e.g. .txt, .md, .unknown), it refuses to guess and reports the full filename. This prevents silently mis-parsing data with the wrong decoder.
Source
Thrown at internal/chezmoi/format.go:72
}
// FormatsByExtension is a map of all Formats by extension.
FormatsByExtension = map[string]Format{
"jsonc": FormatJSONC,
"json": FormatJSON,
"toml": FormatTOML,
"yaml": FormatYAML,
"yml": FormatYAML,
}
FormatExtensions = slices.Sorted(maps.Keys(FormatsByExtension))
)
// UnmarshalFileData unmarshals data in the format guessed from filenameAbsPath.
func UnmarshalFileData(filenameAbsPath AbsPath, data []byte, value any) error {
extension := strings.TrimPrefix(filenameAbsPath.Ext(), ".")
format, ok := FormatsByExtension[extension]
if !ok {
return fmt.Errorf("%s: unknown format", filenameAbsPath)
}
return format.Unmarshal(data, value)
}
// Marshal implements Format.Marshal.
func (formatJSONC) Marshal(value any) ([]byte, error) {
var builder strings.Builder
encoder := json.NewEncoder(&builder)
encoder.SetEscapeHTML(false)
if err := encoder.Encode(value); err != nil {
return nil, err
}
return hujson.Format([]byte(builder.String()))
}
// Name implements Format.Name.
func (formatJSONC) Name() string {
return "jsonc"View on GitHub (pinned to f901167e46)
Solutions
- Rename the file to use a supported extension (.json, .jsonc, .yaml, .yml, .toml)
- Move non-format files out of the source state directory so they are not parsed
- If the content is a supported format, fix the extension to match the actual content
Example fix
// before mv config.yaml myconfig.conf # chezmoi cannot guess format // after mv config.yaml myconfig.yaml
Defensive patterns
Strategy: validation
Validate before calling
supported := map[string]bool{"json":true,"jsonc":true,"yaml":true,"yml":true,"toml":true}
ext := strings.TrimPrefix(filepath.Ext(path), ".")
if !supported[ext] { return fmt.Errorf("%s: no format for extension", path) } Try / catch
if err := chezmoi.UnmarshalFileData(path, data, &v); err != nil {
if strings.Contains(err.Error(), "unknown format") {
// pick a format explicitly or skip the file
}
} Prevention
- Keep source-state files limited to supported extensions
- Never rename format files to arbitrary extensions
- Separate non-format assets from files chezmoi parses
When it happens
Trigger: Calling UnmarshalFileData (directly or via newSourceState) on a source file whose extension is not one of the supported format extensions (json, jsonc, yaml, yml, toml).
Common situations: Adding a source file with an unusual extension, a dotfile like '.foo' whose trimmed extension is empty, renaming a config file to a non-format extension.
Related errors
- %s: %w
- %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/50bad3986066d5f4.
Report an issue: GitHub.