chenhg5/cc-connect · error
codex app-server: create image dir: %w
Error message
codex app-server: create image dir: %w
What it means
Before saving inbound images the session creates <workDir>/.cc-connect/images via os.MkdirAll; when that fails the error is wrapped with this message. It surfaces filesystem problems — permissions, read-only filesystem, or the path existing as a non-directory.
Source
Thrown at agent/codex/appserver_session.go:521
return fmt.Errorf("codex app-server turn/start returned empty turn id")
}
s.stateMu.Lock()
s.currentTurn = resp.Turn.ID
s.pendingMsgs = s.pendingMsgs[:0]
s.stateMu.Unlock()
return nil
}
func (s *appServerSession) stageImages(prompt string, images []core.ImageAttachment) (string, []string, error) {
if len(images) == 0 {
return prompt, nil, nil
}
imgDir := filepath.Join(s.workDir, ".cc-connect", "images")
if err := os.MkdirAll(imgDir, 0o755); err != nil {
return "", nil, fmt.Errorf("codex app-server: create image dir: %w", err)
}
imagePaths := make([]string, 0, len(images))
for i, img := range images {
ext := codexImageExt(img.MimeType)
fname := fmt.Sprintf("img_%d_%d%s", time.Now().UnixMilli(), i, ext)
fpath := filepath.Join(imgDir, fname)
if err := os.WriteFile(fpath, img.Data, 0o644); err != nil {
return "", nil, fmt.Errorf("codex app-server: save image: %w", err)
}
imagePaths = append(imagePaths, fpath)
}
if strings.TrimSpace(prompt) == "" {
prompt = "Please analyze the attached image(s)."
}
return prompt, imagePaths, nilView on GitHub (pinned to 4000b2338a)
Solutions
- Check permissions on s.workDir and ensure the process user can create directories there (chown/chmod)
- Verify nothing named .cc-connect or .cc-connect/images exists as a regular file; remove or rename it
- Point the session's working directory at a writable location in config
- Check disk space / read-only mount (dmesg, mount | grep ro)
Example fix
// before
imgDir := filepath.Join(s.workDir, ".cc-connect", "images")
os.MkdirAll(imgDir, 0o755)
// after — ensure workDir is writable at startup
if err := os.MkdirAll(filepath.Join(s.workDir, ".cc-connect"), 0o755); err != nil {
slog.Error("workdir not writable, fix permissions", "dir", s.workDir, "error", err)
} Defensive patterns
Strategy: validation
Validate before calling
if err := os.MkdirAll(filepath.Join(workDir, ".cc-connect", "images"), 0o755); err != nil {
return fmt.Errorf("workdir not writable for images: %w", err)
} Prevention
- At startup, verify workDir exists and is writable by the service user
- Run the daemon with a dedicated writable WorkingDirectory; never a read-only mount
- Do not place files named .cc-connect in the working directory
- Monitor disk space on the volume hosting workDir
When it happens
Trigger: Calling SendWithImages (a message containing images) when os.MkdirAll(imgDir, 0o755) fails because the working directory is not writable, is read-only, or a file named .cc-connect (or .cc-connect/images) already exists.
Common situations: Running cc-connect as a systemd service with a read-only or root-owned WorkingDirectory; workDir points into a read-only container layer; a stale file named .cc-connect/images exists from a previous misconfiguration; disk full.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- read existing Agy hooks %s: %w
- claudecode: create usage temp dir: %w
- claudecode: chmod per-spawn prompt file 0o644: %w
- codex app-server: save image: %w
- codex: mkdir codex home: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ecc86b73472fe56b.
Report an issue: GitHub.