{"record":{"id":"580d5e6b4b53fce2","repo":"alibaba/open-code-review","slug":"parse-config-w","errorCode":null,"errorMessage":"parse config: %w","messagePattern":"parse config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/config_cmd.go","lineNumber":396,"sourceCode":"// TelemetryConfig holds telemetry-specific settings.\ntype TelemetryConfig struct {\n\tEnabled      bool   `json:\"enabled,omitempty\"`         // Master switch for telemetry\n\tExporter     string `json:\"exporter,omitempty\"`        // \"console\" or \"otlp\"\n\tOTLPEndpoint string `json:\"otlp_endpoint,omitempty\"`   // OTLP collector address\n\tContentLog   bool   `json:\"content_logging,omitempty\"` // Include prompt/response content\n}\n\nfunc loadOrCreateConfig(path string) (*Config, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn &Config{}, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tvar cfg Config\n\tif err := json.Unmarshal(data, &cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse config: %w\", err)\n\t}\n\treturn &cfg, nil\n}\n\n// LoadAppConfig loads config from path. Returns nil, nil if file does not exist.\nfunc LoadAppConfig(path string) (*Config, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"read app config %s: %w\", path, err)\n\t}\n\tvar cfg Config\n\tif err := json.Unmarshal(data, &cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse app config: %w\", err)\n\t}\n\treturn &cfg, nil","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/config_cmd.go#L378-L414","documentation":"loadOrCreateConfig parses the config file with json.Unmarshal into Config and wraps any unmarshal failure as 'parse config: %w'. This means the file was read successfully but its content is not valid JSON, or its JSON does not match the Config schema (e.g. wrong types for fields).","triggerScenarios":"Any config-mutating command ('ocr config set/unset ...') when the existing config file contains malformed JSON or type-incompatible values (e.g. maxTokens as a string instead of number).","commonSituations":"Hand-edited config with a missing comma or trailing comma; comments pasted into JSON; a tool wrote YAML/JSON5 to a .json file; number field changed to string in an editor.","solutions":["Read the wrapped %w message for the exact JSON offset/reason.","Validate the file with a JSON linter (jq . config.json) and fix the syntax or type.","Restore the config from backup or delete it so loadOrCreateConfig recreates an empty one.","Avoid hand-editing; use 'ocr config set' commands to modify values."],"exampleFix":"// before\n{ \"maxTokens\": \"4096\", }\n\n// after\n{ \"maxTokens\": 4096 }","handlingStrategy":"validation","validationCode":"data, err := os.ReadFile(configPath)\nif err != nil { return err }\nvar probe map[string]any\nif err := json.Unmarshal(data, &probe); err != nil {\n    return fmt.Errorf(\"fix config JSON before running ocr config: %w\", err)\n}","typeGuard":"func isConfigJSON(data []byte) bool {\n    var cfg Config\n    return json.Unmarshal(data, &cfg) == nil\n}","tryCatchPattern":"if err := run(); err != nil {\n    var uerr *json.UnmarshalTypeError\n    if errors.As(err, &uerr) {\n        fmt.Fprintf(os.Stderr, \"config field %s has wrong type at offset %d\\n\", uerr.Field, uerr.Offset)\n    }\n}","preventionTips":["Validate config with 'jq . config.json' after any manual edit.","Never put comments or trailing commas in the JSON config.","Keep field types matching the Config struct (numbers as numbers, strings as strings).","Prefer 'ocr config set' over direct file editing."],"tags":["go","json","config","parsing"],"backgroundTag":"config-json-parse-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}