chenhg5/cc-connect · error
read attachment %s: %w
Error message
read attachment %s: %w
What it means
readAttachment wraps any os.Stat failure on an attachment path with `read attachment %s: %w`. The path is cleaned with filepath.Clean before stat; if stat fails the original path is echoed back with the underlying error (typically a fs.ErrNotExist). This is the first gate before the size check and reading the file into memory.
Source
Thrown at cmd/cc-connect/send.go:305
// or invalid config never breaks sending; the caller then falls back to the
// env var / default via resolveMaxAttachmentSize.
func loadSendConfigBestEffort() *config.Config {
cfg, err := config.Load(resolveConfigPath(""))
if err != nil {
return nil
}
return cfg
}
// readAttachment reads a single attachment file, rejecting anything larger than
// maxSize bytes (resolved by the caller from config/env/default). The limit is
// enforced before the file is read into memory.
func readAttachment(path string, maxSize int64) ([]byte, string, string, error) {
cleaned := filepath.Clean(path)
info, err := os.Stat(cleaned)
if err != nil {
return nil, "", "", fmt.Errorf("read attachment %s: %w", path, err)
}
if info.Size() > maxSize {
return nil, "", "", fmt.Errorf("attachment %s exceeds size limit (%d MB)", path, maxSize>>20)
}
data, err := os.ReadFile(cleaned)
if err != nil {
return nil, "", "", fmt.Errorf("read attachment %s: %w", path, err)
}
fileName := filepath.Base(cleaned)
return data, fileName, detectAttachmentMimeType(fileName, data), nil
}
func detectAttachmentMimeType(fileName string, data []byte) string {
ext := strings.ToLower(filepath.Ext(fileName))
switch ext {
case ".md", ".markdown":
return "text/markdown; charset=utf-8"View on GitHub (pinned to 4000b2338a)
Solutions
- Verify the path exists: run `ls -l <path>` exactly as passed to the send command
- Check the working directory — relative paths resolve against it
- If the path is produced by a glob, ensure the glob matches at least one file before invoking the command
Example fix
// before cc-connect send ./attacments/report.pdf // after cc-connect send ./attachments/report.pdf
Defensive patterns
Strategy: validation
Validate before calling
path="./attachments/report.pdf"; [ -e "$path" ] || { echo "missing: $path" >&2; exit 1; } Prevention
- Tab-complete paths to avoid typos
- Use absolute paths in scripts
- Check glob expansion matches non-empty before invoking the command
When it happens
Trigger: Calling loadImageAttachments/loadFileAttachments/loadTypedFileAttachments (via `cc-connect send`) with a path that does not exist or cannot be stat'ed — e.g. a typo'd path, a dangling symlink, or an unreadable parent directory.
Common situations: Typos in attachment paths, running from a different working directory than assumed, shell glob that expanded to nothing and was passed literally, deleted temp files.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- cannot create config directory: %w
- cannot open lock file: %w
- cannot create config directory: %w
- --image requires a path
- --file requires a path
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/1d02f499f77bc5c4.
Report an issue: GitHub.