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

  1. Verify the path exists: run `ls -l <path>` exactly as passed to the send command
  2. Check the working directory — relative paths resolve against it
  3. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/1d02f499f77bc5c4. Report an issue: GitHub.