{"record":{"id":"033c884a4b4ae987","repo":"chenhg5/cc-connect","slug":"write-config-w","errorCode":null,"errorMessage":"write config: %w","messagePattern":"write config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1564,"sourceCode":"\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)\n}\n\n// formatTOML post-processes raw TOML encoder output to improve readability:\n//   - inserts blank lines before section/array-table headers\n//   - removes empty section headers (no key-value pairs between this header and the next)\n//\n// It deliberately keeps all key-value lines intact, including zero-value ones","sourceCodeStart":1546,"sourceCodeEnd":1582,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1546-L1582","documentation":"saveConfig writes the formatted TOML to the temp file with tmp.WriteString; a write failure is cleaned up (temp file closed and removed) and wrapped as \"write config: %w\". This is the in-place write step of the atomic config save.","triggerScenarios":"The WriteString to the already-created temp file fails: filesystem became read-only, disk full/quota hit, I/O error, or the file descriptor entered an error state between creation and write.","commonSituations":"Disk filling up between temp-file creation and write; NFS/network filesystem failures; container storage limits hit mid-save.","solutions":["Free disk space / raise the quota on the volume holding the config directory and retry the operation.","Check the wrapped cause for I/O errors and verify the filesystem health (dmesg, mount options).","Move the config to a reliable local filesystem rather than a network mount."],"exampleFix":"// before\n// no space check before saving\ncfg.Providers = append(cfg.Providers, p)\nsaveConfig(cfg)\n// after\nif err := checkDiskSpace(filepath.Dir(config.ConfigPath)); err != nil {\n    return err\n}\ncfg.Providers = append(cfg.Providers, p)\nsaveConfig(cfg)","handlingStrategy":"retry","validationCode":"if err := checkFreeSpace(filepath.Dir(config.ConfigPath), 1<<20); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"err := saveConfigOp()\nif err != nil && strings.Contains(err.Error(), \"write config\") {\n    time.Sleep(500 * time.Millisecond)\n    err = saveConfigOp() // transient I/O: one retry\n}","preventionTips":["Monitor disk usage and set alerts before volumes fill.","Keep the config on local storage, not network filesystems.","The library already cleans up temp files; do not accumulate .config-*.tmp leftovers in scripts."],"tags":["config","file-io","disk"],"backgroundTag":"file-write-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"}