{"record":{"id":"2f52f9c504299754","repo":"chenhg5/cc-connect","slug":"create-temp-config-w","errorCode":null,"errorMessage":"create temp config: %w","messagePattern":"create temp config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1549,"sourceCode":"\tif ConfigPath == \"\" {\n\t\treturn nil, fmt.Errorf(\"config path not set\")\n\t}\n\tdata, err := os.ReadFile(ConfigPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read config: %w\", err)\n\t}\n\tcfg := &Config{}\n\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()","sourceCodeStart":1531,"sourceCodeEnd":1567,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1531-L1567","documentation":"saveConfig writes atomically by creating a temporary file (os.CreateTemp) in the config directory before renaming it into place. If the temp file cannot be created — directory missing, no write permission, disk full — it returns this wrapped error and nothing is modified.","triggerScenarios":"os.CreateTemp(filepath.Dir(ConfigPath), \".config-*.tmp\") fails: the config directory does not exist, the process lacks write permission on it, or the filesystem is read-only/full.","commonSituations":"Fresh install where ~/.config/cc-connect/ was never created; running the daemon as a system user while the config lives in a human user's home; read-only container root filesystem; disk quota exceeded.","solutions":["Create the config directory first: os.MkdirAll(filepath.Dir(ConfigPath), 0o755).","Check directory permissions so the running user can write (chown/chmod).","Verify free disk space / quota and that the filesystem is mounted writable."],"exampleFix":"// before\nerr := config.UpdateGlobalProvider(\"anthropic\", p)\n// after\nos.MkdirAll(filepath.Dir(config.ConfigPath), 0o755)\nerr := config.UpdateGlobalProvider(\"anthropic\", p)","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(config.ConfigPath)\nif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n    if err := os.MkdirAll(dir, 0o755); err != nil {\n        return err\n    }\n}\nif err := syscall.Access(dir, syscall.O_RDWR); err != nil {\n    return fmt.Errorf(\"config dir not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := config.UpdateGlobalProvider(name, p); err != nil {\n    if strings.Contains(err.Error(), \"create temp config\") {\n        os.MkdirAll(filepath.Dir(config.ConfigPath), 0o755)\n        return config.UpdateGlobalProvider(name, p) // retry\n    }\n    return err\n}","preventionTips":["Ensure the config directory exists before any config write.","Provision correct ownership for the user the daemon runs as (systemd User=).","Monitor disk space/quota on the volume holding the config."],"tags":["config","file-io","temp-file","permissions"],"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-14T05:17:10.506Z"}