charmbracelet/crush · error
failed to marshal provider data: %w
Error message
failed to marshal provider data: %w
What it means
Thrown by cache.Store() when json.Marshal fails to serialize the provider data being cached. Rare in practice because the value is a well-typed struct, but can occur with values containing unsupported types (channels, funcs, cyclic references) when the generic cache[T] is used with a non-marshalable T.
Source
Thrown at internal/config/provider.go:292
return v, "", fmt.Errorf("failed to read provider cache file: %w", err)
}
if err := json.Unmarshal(data, &v); err != nil {
return v, "", fmt.Errorf("failed to unmarshal provider data from cache: %w", err)
}
return v, etag.Of(data), nil
}
func (c cache[T]) Store(v T) error {
slog.Info("Saving provider data to disk", "path", c.path)
if err := os.MkdirAll(filepath.Dir(c.path), 0o755); err != nil {
return fmt.Errorf("failed to create directory for provider cache: %w", err)
}
data, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("failed to marshal provider data: %w", err)
}
// Written through a temporary file and renamed into place. Several Crush
// instances start independently and race to refresh this cache, and a
// truncating write would let one of them read a half-written catalog and
// silently fall back to the bundled copy.
if err := atomicWriteFile(c.path, data, 0o644); err != nil {
return fmt.Errorf("failed to write provider data to cache: %w", err)
}
return nil
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Inspect the value being stored for unsupported JSON types (chan, func, cycles).
- Fix the producer of the data to only include JSON-serializable fields.
- Add json:"-" tags to non-serializable fields in the type parameter T.
- Wrap Marshal yourself with a custom codec if you need special serialization.
Example fix
// before
type P struct { Conn *net.Conn }
// after
type P struct { Conn *net.Conn `json:"-"` } Defensive patterns
Strategy: validation
Validate before calling
if err := json.Marshal(v); err != nil {
// value not serializable; fix before Store
} Type guard
func marshalable[T any](v T) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
if err := cache.Store(v); err != nil {
if strings.Contains(err.Error(), "marshal") {
log.Warn("Skipping cache: value not serializable")
}
} Prevention
- Keep cache type T JSON-safe (no chan/func/cyclic fields)
- Tag internal fields with json:"-"
- Sanitize provider structs before caching
When it happens
Trigger: cache.Store(v) is called with a T that json.Marshal cannot encode: unsupported field types, cycles, or invalid values (NaN) injected into the provider data by a caller.
Common situations: Custom builds/extensions feeding non-serializable data into the generic cache; middlewares mutating provider structs with extra fields of unsupported types.
Related errors
- failed to marshal schema: %w
- failed to unmarshal provider data from cache: %w
- marshal request: %w
- failed to decode response: %w
- error parsing parameters: %s
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/3f685d1d26d3de25.
Report an issue: GitHub.