chenhg5/cc-connect · error
mkdir: %w
Error message
mkdir: %w
What it means
saveAttachment creates ~/.cc-connect/attachments with os.MkdirAll(dir, 0o755) and wraps failures as "mkdir: %w". This fires when the directory tree cannot be created or already exists as a non-directory, typically due to permissions or filesystem state, and aborts SendFile/SendImage.
Source
Thrown at platform/wps-agentspace/wpsagentspace.go:273
if err != nil {
return fmt.Errorf("wps-agentspace: SendImage: %w", err)
}
notice := fmt.Sprintf("🖼 图片已保存到本地:\n%s", path)
return p.sendText(rc.ChatID, notice, rc)
}
// saveAttachment writes data to ~/.cc-connect/attachments/<name> and returns
// the absolute path. The filename is sanitized to a basename to prevent path
// traversal.
func (p *Platform) saveAttachment(name string, data []byte) (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("resolve home dir: %w", err)
}
dir := filepath.Join(home, ".cc-connect", "attachments")
if err := os.MkdirAll(dir, 0o755); err != nil {
return "", fmt.Errorf("mkdir: %w", err)
}
name = filepath.Base(name)
if name == "" || name == "." || name == "/" {
name = fmt.Sprintf("file_%d", time.Now().UnixMilli())
}
path := filepath.Join(dir, name)
if err := os.WriteFile(path, data, 0o644); err != nil {
return "", fmt.Errorf("write: %w", err)
}
return path, nil
}
// Stop gracefully shuts down the platform.
func (p *Platform) Stop() error {
p.stopOnce.Do(func() {
p.stopped.Store(true)
if p.cancel != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped errno with errors.Is(err, os.ErrPermission) / syscall.ENOTDIR / ENOSPC to identify the exact cause.
- Fix ownership/permissions: chown -R the daemon user ~/.cc-connect, or chmod u+rwx on each path component.
- If ~/.cc-connect exists as a file, remove or rename it so the directory can be created.
- Mount a writable volume at ~/.cc-connect (or set HOME to a writable path) in containers.
Example fix
// before: diagnose only from generic failure
if err := os.MkdirAll(dir, 0o755); err != nil {
return "", fmt.Errorf("mkdir: %w", err)
}
// after (caller-side guard)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Join(home, ".cc-connect", "attachments")
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists but is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("cannot create %s: %w", dir, err)
} Try / catch
if _, err := p.SendFile(rc, file); err != nil && strings.HasPrefix(err.Error(), "mkdir:") {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {
slog.Error("permission denied creating attachments dir", "path", pe.Path)
}
} Prevention
- Ensure no regular file occupies ~/.cc-connect or ~/.cc-connect/attachments.
- Run the daemon as the same user that owns $HOME; avoid mixing root and user runs.
- In containers, mount a writable volume for the attachments directory or use a read-write rootfs.
- Check SELinux/AppArmor policies allow the daemon user to write under $HOME.
When it happens
Trigger: SendFile or SendImage when: $HOME is read-only or owned by another user; a component of the path (~/.cc-connect or ~/.cc-connect/attachments) exists as a regular file; the filesystem is read-only or full; SELinux/AppArmor denies the write.
Common situations: Container images with read-only rootfs; daemons running as non-root users while ~/.cc-connect was created by root during manual testing; macOS sandboxed launchd contexts; immutable infrastructure mounts.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- create Agy permission overlay: %w
- read existing Agy hooks %s: %w
- codex: mkdir codex home: %w
- kimi: read sessions dir: %w
- cannot create config directory: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/dc8499d37edcb5e4.
Report an issue: GitHub.