multica-ai/multica · error
upload attachment %s: %w
Error message
upload attachment %s: %w
What it means
While adding a comment with attachments, each pre-validated local file is uploaded via client.UploadFile to the issue. This error wraps the failure of one upload (I/O read error, size limit, auth, 5xx) and names the offending file path. Note uploads happen after all files were validated, but a mid-loop failure can still leave earlier attachments orphaned — retrying will re-upload.
Source
Thrown at server/cmd/multica/cmd_issue.go:2000
return fmt.Errorf("resolve issue: %w", err)
}
issueID := issueRef.ID
// Validate and read ALL attachments before uploading any. URLs are skipped
// with a warning — `--attachment` only accepts local file paths. Reading
// everything up front means a later invalid path (external / symlink escape
// caught by the workdir guard) aborts the call with ZERO uploads, instead
// of leaving an earlier file uploaded as an orphaned issue attachment while
// the comment is never posted (which would duplicate on retry — MUL-4252).
pending, err := collectLocalAttachments(cmd, attachments)
if err != nil {
return err
}
var attachmentIDs []string
for _, att := range pending {
id, uploadErr := client.UploadFile(ctx, att.data, att.path, issueID)
if uploadErr != nil {
return fmt.Errorf("upload attachment %s: %w", att.path, uploadErr)
}
attachmentIDs = append(attachmentIDs, id)
fmt.Fprintf(os.Stderr, "Uploaded %s\n", att.path)
}
body := map[string]any{"content": content}
if parentID, _ := cmd.Flags().GetString("parent"); parentID != "" {
body["parent_id"] = parentID
}
if len(attachmentIDs) > 0 {
body["attachment_ids"] = attachmentIDs
}
var result map[string]any
if err := client.PostJSON(ctx, "/api/issues/"+issueID+"/comments", body, &result); err != nil {
return fmt.Errorf("add comment: %w", err)
}
fmt.Fprintf(os.Stderr, "Comment added to issue %s.\n", issueRef.Display)View on GitHub (pinned to 2c0912b6ec)
Solutions
- Retry the command once transient network issues clear.
- Reduce the attachment size or split it (compress, split archives).
- Confirm the file is a regular local file inside the workdir (no symlinks escaping it — the collect step would have caught that earlier).
- Check server logs / upload limits if the failure is deterministic.
Defensive patterns
Strategy: retry
Validate before calling
# bash: pre-check every attachment is a readable regular file
for f in "${ATTACHMENTS[@]}"; do
[[ -f "$f" && -r "$f" ]] || { echo "bad attachment: $f" >&2; exit 2; }
sz=$(stat -c%s "$f"); [[ $sz -le $MAX_UPLOAD ]] || { echo "$f exceeds $MAX_UPLOAD bytes" >&2; exit 2; }
done Try / catch
# bash: retry uploads once; report orphans on repeated failure
multica issue comment add "$ISSUE" --content "$BODY" "${ATT[@]/#/--attachment }" || {
echo "upload failed — earlier files may be orphaned on the issue; check before re-running" >&2; exit 1;
} Prevention
- Size-check and readability-check attachments before the CLI call.
- Keep attachments small or upload during stable network windows; remember a failed retry can orphan already-uploaded files.
When it happens
Trigger: `multica issue comment add <issue> --attachment big.bin` where the file exceeds a server size limit, the connection drops mid-upload, or the 60s-extended timeout is still too short for a very large/slow upload.
Common situations: Attaching large binaries over slow links; server-side upload restrictions; flaky networks causing truncated multipart requests.
Related errors
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/f4db327e9e7d9d6f.
Report an issue: GitHub.