{"record":{"id":"582e1a4b7bdb8b96","repo":"multica-ai/multica","slug":"create-temp-config-file-w","errorCode":null,"errorMessage":"create temp config file: %w","messagePattern":"create temp config file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/cli/config.go","lineNumber":356,"sourceCode":"\t\t\t}\n\t\t\tif current == root {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent := filepath.Dir(current)\n\t\t\tif parent == current {\n\t\t\t\treturn fmt.Errorf(\"task-local CLI config directory %q escapes root %q\", dir, root)\n\t\t\t}\n\t\t}\n\t}\n\tdata, err := json.MarshalIndent(cfg, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encode CLI config: %w\", err)\n\t}\n\n\t// Write to a temp file in the same directory, then rename for atomicity.\n\ttmp, err := os.CreateTemp(dir, \".config-*.json.tmp\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create temp config file: %w\", err)\n\t}\n\ttmpPath := tmp.Name()\n\tif _, err := tmp.Write(append(data, '\\n')); err != nil {\n\t\ttmp.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"write temp config file: %w\", err)\n\t}\n\tif err := tmp.Close(); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"close temp config file: %w\", err)\n\t}\n\tif err := os.Chmod(tmpPath, 0o600); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"chmod temp config file: %w\", err)\n\t}\n\tif err := os.Rename(tmpPath, path); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"rename config file: %w\", err)","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/cli/config.go#L338-L374","documentation":"The atomic-write sequence creates a temp file (.config-*.json.tmp) in the config directory before renaming it over the final path; os.CreateTemp failed. This is almost always a permission or disk-space error on the just-created directory, since the directory was verified moments earlier.","triggerScenarios":"Calling SaveCLIConfig when the config directory becomes unwritable between MkdirAll and CreateTemp (racing chmod by the task-local walk, wrong ownership), when the disk is full, or when the filesystem disallows the O_EXCL create pattern.","commonSituations":"Disk full on the home partition; a security tool or immutable attribute blocking file creation; the directory being on a full tmpfs when MULTICA_TASK_CONFIG_ROOT points into /tmp.","solutions":["Check free space on the filesystem holding the config path (df)","Verify write permission on the directory from the wrapped error path","Clear immutable attributes (chattr -i) or security-software locks if present","If using a /tmp-backed task root, move MULTICA_TASK_CONFIG_ROOT to persistent storage"],"exampleFix":"# before\n$ multica config set ...\ncreate temp config file: open /home/user/.multica/.config-123.json.tmp: no space left on device\n\n# after\n$ df -h /home  # free space, then retry\n$ multica config set ...","handlingStrategy":"retry","validationCode":"var stat syscall.Statfs_t\nif err := syscall.Statfs(dir, &stat); err == nil && stat.Bavail == 0 {\n\t// no free space; alert before attempting the save\n}","typeGuard":null,"tryCatchPattern":"if err := cli.SaveCLIConfig(cfg); err != nil && errors.Is(err, syscall.ENOSPC) {\n\t// surface a disk-space alert; config file is untouched thanks to atomic write\n}","preventionTips":["Monitor free space on the filesystem holding the config root","Avoid /tmp-backed task roots with small tmpfs limits","Retry saves after freeing space — the previous config remains intact"],"tags":["filesystem","disk-space","config","go"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}