{"record":{"id":"eaf5fb26bf41a5cd","repo":"chenhg5/cc-connect","slug":"codex-app-server-save-image-w","errorCode":null,"errorMessage":"codex app-server: save image: %w","messagePattern":"codex app-server: save image: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/codex/appserver_session.go","lineNumber":530,"sourceCode":"}\n\nfunc (s *appServerSession) stageImages(prompt string, images []core.ImageAttachment) (string, []string, error) {\n\tif len(images) == 0 {\n\t\treturn prompt, nil, nil\n\t}\n\n\timgDir := filepath.Join(s.workDir, \".cc-connect\", \"images\")\n\tif err := os.MkdirAll(imgDir, 0o755); err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"codex app-server: create image dir: %w\", err)\n\t}\n\n\timagePaths := make([]string, 0, len(images))\n\tfor i, img := range images {\n\t\text := codexImageExt(img.MimeType)\n\t\tfname := fmt.Sprintf(\"img_%d_%d%s\", time.Now().UnixMilli(), i, ext)\n\t\tfpath := filepath.Join(imgDir, fname)\n\t\tif err := os.WriteFile(fpath, img.Data, 0o644); err != nil {\n\t\t\treturn \"\", nil, fmt.Errorf(\"codex app-server: save image: %w\", err)\n\t\t}\n\t\timagePaths = append(imagePaths, fpath)\n\t}\n\n\tif strings.TrimSpace(prompt) == \"\" {\n\t\tprompt = \"Please analyze the attached image(s).\"\n\t}\n\n\treturn prompt, imagePaths, nil\n}\n\nfunc (s *appServerSession) RespondPermission(requestID string, result core.PermissionResult) error {\n\ts.approvalsMu.Lock()\n\tch := s.pendingApprovals[requestID]\n\ts.approvalsMu.Unlock()\n\tif ch == nil {\n\t\treturn fmt.Errorf(\"codex app-server: no pending approval for request %s\", requestID)\n\t}","sourceCodeStart":512,"sourceCodeEnd":548,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/codex/appserver_session.go#L512-L548","documentation":"After creating the image directory the session writes each image to disk with os.WriteFile; a failure here is wrapped as 'save image'. This indicates the directory was created but an individual file write failed — typically permissions, disk space, or a race removing the directory mid-write.","triggerScenarios":"os.WriteFile(fpath, img.Data, 0o644) fails while persisting an attachment inside <workDir>/.cc-connect/images before sending it to the app-server.","commonSituations":"Disk quota/full disk when saving large images; another process (cleanup cron) deleting .cc-connect/images concurrently; restrictive umask or SELinux/AppArmor blocking writes; filename collision overwriting is not the issue but ENOSPC/EDQUOT commonly is.","solutions":["Check disk space and quota on the volume holding workDir (df -h)","Ensure the process user has write permission on .cc-connect/images and no security module blocks writes","Stop concurrent cleanup jobs touching .cc-connect while a session is active","Check the wrapped errno in the error string (ENOSPC, EACCES, ENOENT) to target the fix"],"exampleFix":"// before\nif err := os.WriteFile(fpath, img.Data, 0o644); err != nil {\n    return \"\", nil, fmt.Errorf(\"codex app-server: save image: %w\", err)\n}\n// after\nif err := os.WriteFile(fpath, img.Data, 0o644); err != nil {\n    slog.Warn(\"image save failed\", \"path\", fpath, \"bytes\", len(img.Data), \"error\", err)\n    return \"\", nil, fmt.Errorf(\"codex app-server: save image %s: %w\", fpath, err)\n}","handlingStrategy":"validation","validationCode":"fi, err := os.Stat(imgDir)\nif err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"image dir missing or not a directory: %s\", imgDir)\n}\ntest, err := os.CreateTemp(imgDir, \"wtest*\")\nif err != nil { return fmt.Errorf(\"image dir not writable: %w\", err) }\ntest.Close(); os.Remove(test.Name())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check free disk space before saving large attachments","Exclude .cc-connect/images from cleanup crons while sessions are active","Log the target path and bytes with the error for diagnosis","Verify SELinux/AppArmor policies allow writes for the service user"],"tags":["filesystem","images","file-write"],"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"}