{"record":{"id":"664d31665f68762c","repo":"charmbracelet/crush","slug":"failed-to-update-preferred-small-model-w","errorCode":null,"errorMessage":"failed to update preferred small model: %w","messagePattern":"failed to update preferred small model: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/load.go","lineNumber":161,"sourceCode":"\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\n}\n\n// mustMarshalConfig marshals the config to JSON bytes, returning empty JSON on\n// error.\nfunc mustMarshalConfig(cfg *Config) []byte {\n\tdata, err := json.Marshal(cfg)\n\tif err != nil {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/load.go#L143-L179","documentation":"Same as the large-model case: when the preferred small model needed a fallback correction, Load() persists it to the global config and returns this wrapped error if the write fails.","triggerScenarios":"resolved.SmallFallback is true and store.updateLocked(ScopeGlobal, updatePreferredModelFields...) errors while persisting the corrected small model selection.","commonSituations":"Read-only or unwritable global config; corrupted global crush.json; disk-full; containerized environments mounting the config dir read-only.","solutions":["Make the global config file writable (chmod/chown)","Validate and repair the global config JSON","Check disk space","Explicitly set a valid small preferred model in config so no fallback correction is needed"],"exampleFix":"// before\n\"options\": {\"preferred_model\": {\"small\": \"gpt-3.5-turbo-0301\"}}  // stale, triggers fallback write\n// after\n\"options\": {\"preferred_model\": {\"small\": \"openai/gpt-4o-mini\"}}  // valid, no fallback write needed","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 small model:\") {\n        return fmt.Errorf(\"global config unwritable or corrupt: %w\", err)\n    }\n    return err\n}","preventionTips":["Set a valid small preferred model explicitly to avoid fallback writes","Keep the global config writable and valid JSON","Avoid running crush as different users sharing one config dir","Check disk space and file ownership after environment changes"],"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"}