{"record":{"id":"44b395873579daee","repo":"multica-ai/multica","slug":"write-file-w","errorCode":null,"errorMessage":"write file: %w","messagePattern":"write file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_attachment.go","lineNumber":172,"sourceCode":"\t// Download the file content.\n\tdata, err := client.DownloadFile(ctx, downloadURL)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"download file: %w\", err)\n\t}\n\n\t// Write to the output directory, creating it if needed so `-o` works\n\t// against a directory that does not exist yet (the help example's\n\t// `-o ./attachments` in a clean workdir).\n\toutputDir, _ := cmd.Flags().GetString(\"output-dir\")\n\tif outputDir != \"\" {\n\t\tif err := os.MkdirAll(outputDir, 0o755); err != nil {\n\t\t\treturn fmt.Errorf(\"create output directory: %w\", err)\n\t\t}\n\t}\n\tdestPath := filepath.Join(outputDir, filename)\n\n\tif err := os.WriteFile(destPath, data, 0o644); err != nil {\n\t\treturn fmt.Errorf(\"write file: %w\", err)\n\t}\n\n\t// Print the absolute path so agents can reference the file.\n\tabs, err := filepath.Abs(destPath)\n\tif err != nil {\n\t\tabs = destPath\n\t}\n\tfmt.Fprintln(os.Stderr, \"Downloaded:\", abs)\n\n\t// Also print as JSON for --output json compatibility.\n\treturn cli.PrintJSON(os.Stdout, map[string]any{\n\t\t\"id\":       strVal(att, \"id\"),\n\t\t\"filename\": filename,\n\t\t\"path\":     abs,\n\t\t\"size\":     strVal(att, \"size_bytes\"),\n\t})\n}\n","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_attachment.go#L154-L190","documentation":"Final write of the downloaded bytes with os.WriteFile to destPath = filepath.Join(outputDir, filename). Wraps OS write errors: permission denied, destination is a directory, disk full, or name too long.","triggerScenarios":"The server-supplied filename collides with an existing directory name in the output dir; output dir not writable; disk full; filename from metadata containing path separators or being extremely long (filesystem limit).","commonSituations":"Attachments named like `data` colliding with an existing `data/` directory; running as non-root into /mnt dirs; full disks on small VMs/containers; unusual unicode filenames from other OSes hitting filesystem limits.","solutions":["Check `df -h <dir>` for space and `ls -l` the destination for a directory/filename collision; rename or remove the conflict","Ensure the output directory is writable by the current user","Download to a different output dir (-o /tmp/att) to isolate a bad destination","If filename looks pathological, rename after download"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# check for directory/filename collision and writability before download\n[ ! -d \"./attachments/$expected_name\" ] || { echo 'name collides with a directory' >&2; exit 1; }\n[ -w ./attachments ] || { echo 'output dir not writable' >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Download into an empty scratch dir per attachment to avoid filename collisions","Monitor disk space in long-running download loops"],"tags":["cli","attachment","filesystem","download"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}