twpayne/chezmoi · error
%s: parse error
Error message
%s: parse error
What it means
parseOSRelease reads an /etc/os-release style file into a key/value map. Every non-comment, non-empty line must contain an '=' separating key and value; a line without '=' causes this error, reported with the offending line content. It signals a malformed or non-os-release file being parsed.
Source
Thrown at internal/chezmoi/data.go:91
func maybeUnquote(s string) string {
if unquotedS, err := unquote(s); err == nil {
return unquotedS
}
return s
}
// parseOSRelease parses operating system identification data from r as defined
// by the os-release specification.
func parseOSRelease(data []byte) (map[string]any, error) {
result := make(map[string]any)
for line := range bytes.Lines(data) {
token := bytes.TrimSpace(line)
if len(token) == 0 || token[0] == '#' {
continue
}
key, value, ok := bytes.Cut(token, []byte{'='})
if !ok {
return nil, fmt.Errorf("%s: parse error", token)
}
result[string(key)] = maybeUnquote(string(value))
}
return result, nil
}
func unquote(s string) (string, error) {
switch {
case len(s) < 2:
fallthrough
case s[0] != '"' && s[0] != '\'':
fallthrough
case s[0] != s[len(s)-1]:
return "", strconv.ErrSyntax
case strings.IndexByte(s, '\\') == -1:
return s[1 : len(s)-1], nil
}
bs := []byte(s[1 : len(s)-1])View on GitHub (pinned to f901167e46)
Solutions
- Inspect the os-release file being parsed and fix the malformed line to key=value form
- Restore the stock /etc/os-release from the distro package (e.g. reinstall the base-files/os-release package)
- If a custom file is being fed in, correct or remove the offending line
Example fix
// before: broken os-release line NAME="Debian GNU/Linux" Debian 12 // after NAME="Debian GNU/Linux" VERSION="12 (bookworm)"
Defensive patterns
Strategy: validation
Validate before calling
for i, line := range bytes.Split(data, []byte{'\n'}) {
line = bytes.TrimSpace(line)
if len(line) == 0 || line[0] == '#' { continue }
if !bytes.Contains(line, []byte{'='}) {
return fmt.Errorf("line %d has no '=': %q", i+1, line)
}
} Try / catch
osRelease, err := OSRelease()
if err != nil && strings.HasSuffix(err.Error(), "parse error") {
// treat as unknown OS / use fallback detection
} Prevention
- Do not hand-edit /etc/os-release; use distro packages to manage it
- Validate any custom os-release-like files are strict key=value
- Strip CRLF and comments before parsing custom files
When it happens
Trigger: Calling OSRelease (or the anonymous caller) on a file whose content has a line without 'key=value' form — e.g. a custom os-release override missing '=', stray prose, or CRLF/binary garbage.
Common situations: Pointing chezmoi at a wrong file for OS release detection, a customized /etc/os-release broken by manual edits, container images shipping a stub os-release with junk lines.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/69e872331b8da567.
Report an issue: GitHub.