{"record":{"id":"eb9512fc85ecb2f0","repo":"charmbracelet/crush","slug":"failed-to-update-preferred-large-model-w","errorCode":null,"errorMessage":"failed to update preferred large model: %w","messagePattern":"failed to update preferred large model: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/load.go","lineNumber":154,"sourceCode":"\n\tif !cfg.IsConfigured() {\n\t\tslog.Warn(\"No providers configured\")\n\t\treturn store, nil\n\t}\n\n\tresolved, err := resolveSelectedModels(cfg, store.knownProviders)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to configure selected models: %w\", err)\n\t}\n\tcfg.Models[SelectedModelTypeLarge] = resolved.Large\n\tcfg.Models[SelectedModelTypeSmall] = resolved.Small\n\n\t// Persist any fallback corrections while we still hold writeMu.\n\tif resolved.LargeFallback {\n\t\tif err := store.updateLocked(ScopeGlobal, func(c *Config) map[string]any {\n\t\t\treturn store.updatePreferredModelFields(c, SelectedModelTypeLarge, resolved.Large)\n\t\t}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to update preferred large model: %w\", err)\n\t\t}\n\t}\n\tif resolved.SmallFallback {\n\t\tif err := store.updateLocked(ScopeGlobal, func(c *Config) map[string]any {\n\t\t\treturn store.updatePreferredModelFields(c, SelectedModelTypeSmall, resolved.Small)\n\t\t}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to update preferred small model: %w\", err)\n\t\t}\n\t}\n\tstore.SetupAgents()\n\n\t// Capture initial staleness snapshot\n\t// Capture initial staleness snapshot. Track every discovered config path,\n\t// not just the ones that loaded, so a config file created after startup\n\t// (e.g. a crushrc added mid-session) is detected as a change.\n\tstore.captureStalenessSnapshot(append(slices.Clone(configPaths), loadedPaths...))\n\n\treturn store, nil","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/load.go#L136-L172","documentation":"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.","triggerScenarios":"resolved.LargeFallback is true and store.updateLocked(ScopeGlobal, ...) returns an error — typically a file write/permission failure or marshaling error on the global config.","commonSituations":"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.","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"],"exampleFix":"// before\n$ ls -l ~/.config/crush/crush.json\n-r--r--r-- ... (read-only)\n// after\n$ chmod u+w ~/.config/crush/crush.json\ncrush  // loads and persists corrected model","handlingStrategy":"try-catch","validationCode":"fi, err := os.Stat(globalConfigPath)\nif err == nil && fi.Mode().Perm()&0o200 == 0 {\n    return fmt.Errorf(\"global config %s is not writable\", globalConfigPath)\n}","typeGuard":null,"tryCatchPattern":"store, err := config.Load(ctx, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to update preferred large model:\") {\n        // global config not writable; chmod or fix disk, then retry\n        return fmt.Errorf(\"fix global config permissions: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["config","persistence","filesystem"],"backgroundTag":"config-write-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}