{"record":{"id":"0a30a0f786ae7f0e","repo":"chenhg5/cc-connect","slug":"encode-config-w","errorCode":null,"errorMessage":"encode config: %w","messagePattern":"encode config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1557,"sourceCode":"\tif err := toml.Unmarshal(data, cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse config: %w\", err)\n\t}\n\treturn cfg, nil\n}\n\nfunc saveConfig(cfg *Config) error {\n\tdir := filepath.Dir(ConfigPath)\n\ttmp, err := os.CreateTemp(dir, \".config-*.tmp\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create temp config: %w\", err)\n\t}\n\ttmpPath := tmp.Name()\n\n\tvar buf strings.Builder\n\tif err := toml.NewEncoder(&buf).Encode(cfg); err != nil {\n\t\ttmp.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"encode config: %w\", err)\n\t}\n\n\tformatted := formatTOML(buf.String())\n\tif _, err := tmp.WriteString(formatted); err != nil {\n\t\ttmp.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"write config: %w\", err)\n\t}\n\tif err := tmp.Sync(); err != nil {\n\t\ttmp.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn err\n\t}\n\tif err := tmp.Close(); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn err\n\t}\n\treturn os.Rename(tmpPath, ConfigPath)","sourceCodeStart":1539,"sourceCodeEnd":1575,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1539-L1575","documentation":"saveConfig encodes the in-memory Config struct to TOML in memory before writing; if toml.NewEncoder(&buf).Encode(cfg) fails, it cleans up the temp file and returns this wrapped error. This indicates the Config value cannot be represented as TOML — rare, since the struct is designed for TOML round-tripping.","triggerScenarios":"A Config struct containing a field type the TOML encoder cannot serialize (e.g. map with non-string keys, unsupported nested types) — typically only possible if Config was constructed programmatically with unusual values rather than loaded from a file.","commonSituations":"Programmatic config construction with non-string map keys or custom types assigned into map[string]any options; a schema change introducing a type the encoder rejects; memory/corruption edge cases.","solutions":["Inspect the wrapped encoder error for the offending field and change its value/type to a TOML-representable one (e.g. use map[string]any with string keys).","Load the config via the library's Load path (which validates types) before mutating, instead of constructing Config from scratch.","If a recent code change introduced a new Config field, ensure it has a TOML-compatible type and proper struct tags."],"exampleFix":"// before\ncfg.Extra = map[int]string{1: \"x\"} // non-string keys\n// after\ncfg.Extra = map[string]any{\"1\": \"x\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := saveConfigOp(); err != nil {\n    if strings.Contains(err.Error(), \"encode config\") {\n        // reload a pristine config from disk to drop the offending value\n        cfg, lerr := config.Load()\n        if lerr == nil { return reapplySafe(cfg) }\n    }\n    return err\n}","preventionTips":["Only mutate Config obtained from the library's Load, never construct it ad hoc.","Keep map[string]any option values TOML-encodable (string keys, scalars).","Add a round-trip test (load -> save -> load) when adding new Config fields."],"tags":["config","toml","serialization"],"backgroundTag":"json-serialization-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}