JanDeDobbeleer/oh-my-posh · error
failed to marshal segment %s: %w
Error message
failed to marshal segment %s: %w
What it means
While recording the export data document, each configured segment's writer is serialized via recordSegmentData. If marshaling a segment's data fails, buildDataDocument aborts naming the segment: "failed to marshal segment <key>: <reason>". It means one segment type produced data json.Marshal cannot encode (or recordSegmentData hit an internal error).
Source
Thrown at src/cli/config_export_data.go:161
// SegmentsCache is internal cache plumbing, and Var is already covered
// by the config's own "var" section - neither belongs in a recorded
// data file.
delete(envFields, "SegmentsCache")
delete(envFields, "Var")
segments := make(map[string]json.RawMessage)
for _, block := range cfg.Blocks {
for _, segment := range block.Segments {
writer := segment.Writer()
if writer == nil {
continue
}
raw, methods, err := recordSegmentData(writer)
if err != nil {
return nil, fmt.Errorf("failed to marshal segment %s: %w", segment.DataKey(), err)
}
recorded := config.RecordedSegment{Data: raw, Methods: methods, Enabled: segment.Enabled}
recordedRaw, err := json.Marshal(recorded)
if err != nil {
return nil, fmt.Errorf("failed to marshal segment %s: %w", segment.DataKey(), err)
}
key := segment.DataKey()
if _, exists := segments[key]; exists {
fmt.Fprintf(os.Stderr, "warning: multiple segments share the data key %q; the last one wins - add an alias to disambiguate\n", key)
}
segments[key] = recordedRaw
}
}
View on GitHub (pinned to 0976794618)
Solutions
- Identify the segment named in the message and check the wrapped cause for the exact field
- Update oh-my-posh; if recent, this may be a regression — report it with the wrapped error
- Temporarily disable the offending segment in the config to unblock the export
- For segment developers: give the offending field a json:"-" tag or a MarshalJSON implementation
Example fix
// before
type gitData struct { Hooks map[int]string `json:"hooks"` }
// after
type gitData struct { Hooks map[int]string `json:"-"` } // or map[string]string Defensive patterns
Strategy: try-catch
Type guard
// Go: check segment data encodes cleanly before recording
func segmentDataEncodable(writer segments.SegmentWriter) bool {
raw, _, err := recordSegmentData(writer)
return err == nil && json.Valid(raw)
} Try / catch
if err := runDataExport(cfg); err != nil {
var segErr interface{ Unwrap() error }
if strings.Contains(err.Error(), "failed to marshal segment") {
fmt.Fprintf(os.Stderr, "offending segment identified in: %v\n", err)
os.Exit(1)
}
return err
} Prevention
- Bisect by disabling segments in the config until the named segment is isolated
- For new segments, unit test that their data marshals to valid JSON
- Tag internal fields json:"-" so they never reach recorded output
- Keep oh-my-posh current; marshal failures in stock segments are usually fixed upstream quickly
When it happens
Trigger: Running `oh-my-posh config export data` with a config containing a segment whose writer data is unmarshalable — typically a map keyed by a non-string type, an invalid value, or a func/channel field in a segment's response struct.
Common situations: Buggy or experimental segment data after an oh-my-posh update; a custom config exercising a rarely recorded segment (e.g. odd API response shapes cached into a segment's data); developing a new segment with an unmarshalable field.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to marshal template cache: %w
- failed to record theme %s: %w
- failed to parse segments in data file: %w
- failed to parse nerd fonts release
- failed to parse theme %s
AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31).
Data as JSON: /api/errors/52111eb42a899807.
Report an issue: GitHub.