{"record":{"id":"596548dfdd9b7232","repo":"sipeed/picoclaw","slug":"failed-to-load-config-w-596548","errorCode":null,"errorMessage":"failed to load config: %w","messagePattern":"failed to load config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/model/add.go","lineNumber":163,"sourceCode":"\t\t\t\tfmt.Fprintf(stdout, \"Out of range. Enter 1-%d.\\n\", len(entries))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn entries[idx-1].ID, nil\n\t\t}\n\t\tfor _, m := range entries {\n\t\t\tif m.ID == text {\n\t\t\t\treturn m.ID, nil\n\t\t\t}\n\t\t}\n\t\tfmt.Fprintln(stdout, \"Not a valid number or model id; try again.\")\n\t}\n}\n\nfunc upsertModelDefault(apiBase, apiKey, alias, modelID string, stdout io.Writer) error {\n\tconfigPath := internal.GetConfigPath()\n\tcfg, err := config.LoadConfig(configPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load config: %w\", err)\n\t}\n\n\tsecureKeys := config.SimpleSecureStrings(apiKey)\n\n\tfound := false\n\tfor _, m := range cfg.ModelList {\n\t\tif m == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif m.ModelName == alias {\n\t\t\tm.Model = modelID\n\t\t\tm.APIBase = apiBase\n\t\t\tm.APIKeys = secureKeys\n\t\t\tm.Enabled = true\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/model/add.go#L145-L181","documentation":"picoclaw model add updated nothing yet — it failed while loading the existing config file (config.LoadConfig on the path from internal.GetConfigPath) before upserting the model entry. The wrapped error is the real cause: YAML/JSON syntax errors with a line/column, schema validation failures for unknown or ill-typed fields, or filesystem errors such as permission denied.","triggerScenarios":"Hand-editing the config and breaking indentation or value types; a config written by a newer picoclaw version containing fields this version's validator rejects; a truncated file after a crash mid-write; an unreadable file (wrong owner, restrictive mode).","commonSituations":"Editors inserting tabs into YAML; sharing one config across machines with different picoclaw versions; automation templates with syntax slips; interrupted saves.","solutions":["Read the wrapped message — it usually pinpoints the failing line/column or field","Run a YAML/JSON linter on the reported config path","Fix the field, restore a backup, or move the broken file aside and let picoclaw regenerate it, then re-add entries","If the error is a read failure, fix ownership/permissions on the file"],"exampleFix":"# before (config file; tab indentation broke YAML)\nmodel_list:\n\t- model_name: custom-prefer\n\n# after\nmodel_list:\n  - model_name: custom-prefer","handlingStrategy":"validation","validationCode":"configPath := internal.GetConfigPath()\nif raw, err := os.ReadFile(configPath); err == nil {\n  var probe map[string]any\n  if json.Unmarshal(raw, &probe) != nil && yaml.Unmarshal(raw, &probe) != nil {\n    return fmt.Errorf(\"config at %s is neither valid JSON nor YAML; fix before running\", configPath)\n  }\n}","typeGuard":"func isConfigLoadError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"failed to load config\")\n}","tryCatchPattern":"if err := runAdd(opt); err != nil {\n  if isConfigLoadError(err) {\n    // show the config path and the wrapped parse error; suggest restoring a backup\n  }\n  return err\n}","preventionTips":["Back up the config before hand-editing","Use spaces (never tabs) in the YAML config","Keep picoclaw versions consistent across machines sharing a config"],"tags":["config","cli","yaml","persistence"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}