charmbracelet/crush · error
failed to update preferred large model: %w
Error message
failed to update preferred large model: %w
What it means
When resolveSelectedModels applies a fallback correction to the preferred large model (e.g. the selected model no longer exists and was swapped), Load() persists that correction to the global-scope config via store.updateLocked. If the write fails, Load aborts with this wrapped error.
Source
Thrown at internal/config/load.go:154
if !cfg.IsConfigured() {
slog.Warn("No providers configured")
return store, nil
}
resolved, err := resolveSelectedModels(cfg, store.knownProviders)
if err != nil {
return nil, fmt.Errorf("failed to configure selected models: %w", err)
}
cfg.Models[SelectedModelTypeLarge] = resolved.Large
cfg.Models[SelectedModelTypeSmall] = resolved.Small
// Persist any fallback corrections while we still hold writeMu.
if resolved.LargeFallback {
if err := store.updateLocked(ScopeGlobal, func(c *Config) map[string]any {
return store.updatePreferredModelFields(c, SelectedModelTypeLarge, resolved.Large)
}); err != nil {
return nil, fmt.Errorf("failed to update preferred large model: %w", err)
}
}
if resolved.SmallFallback {
if err := store.updateLocked(ScopeGlobal, func(c *Config) map[string]any {
return store.updatePreferredModelFields(c, SelectedModelTypeSmall, resolved.Small)
}); err != nil {
return nil, fmt.Errorf("failed to update preferred small model: %w", err)
}
}
store.SetupAgents()
// Capture initial staleness snapshot
// Capture initial staleness snapshot. Track every discovered config path,
// not just the ones that loaded, so a config file created after startup
// (e.g. a crushrc added mid-session) is detected as a change.
store.captureStalenessSnapshot(append(slices.Clone(configPaths), loadedPaths...))
return store, nilView on GitHub (pinned to 7944b8e522)
Solutions
- Check write permissions on the global config file/directory and fix with chmod/chown
- Fix the global config content if it is corrupted (validate JSON)
- Free disk space if the disk is full
- Run crush once with correct permissions so the fallback model is persisted, instead of ignoring the correction
Example fix
// before $ ls -l ~/.config/crush/crush.json -r--r--r-- ... (read-only) // after $ chmod u+w ~/.config/crush/crush.json crush // loads and persists corrected model
Defensive patterns
Strategy: try-catch
Validate before calling
fi, err := os.Stat(globalConfigPath)
if err == nil && fi.Mode().Perm()&0o200 == 0 {
return fmt.Errorf("global config %s is not writable", globalConfigPath)
} Try / catch
store, err := config.Load(ctx, opts)
if err != nil {
if strings.Contains(err.Error(), "failed to update preferred large model:") {
// global config not writable; chmod or fix disk, then retry
return fmt.Errorf("fix global config permissions: %w", err)
}
return err
} Prevention
- Ensure the config directory is owned by the running user
- Avoid mounting config dirs read-only in containers
- Monitor disk space on machines running crush
- Validate global config JSON periodically to prevent marshal failures
When it happens
Trigger: resolved.LargeFallback is true and store.updateLocked(ScopeGlobal, ...) returns an error — typically a file write/permission failure or marshaling error on the global config.
Common situations: Global config file is read-only or owned by another user; disk full; global config corrupted so re-marshaling fails; running in a sandbox where the config dir is not writable.
Related errors
- failed to persist docker mcp configuration: %w
- failed to update preferred small model: %w
- docker MCP started but failed to persist configuration: %w
- failed to load projects: %w
- failed to check init flag file: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/eb9512fc85ecb2f0.
Report an issue: GitHub.