paperclipai/paperclip · warning
Skipped ${applied.skippedMissingAttachmentObjects} attachmen
Error message
Skipped ${applied.skippedMissingAttachmentObjects} attachments whose source files were missing from storage. What it means
After a confirmed worktree import, applyMergePlan inserted rows into the target; attachments whose database rows were planned but whose backing object files were absent from source storage were skipped and counted in skippedMissingAttachmentObjects. The import still completes — only those attachment payloads are missing in the target.
Source
Thrown at cli/src/commands/worktree.ts:4232
? true
: await p.confirm({
message: `Import ${collected.plan.counts.issuesToInsert} issues and ${collected.plan.counts.commentsToInsert} comments from ${sourceEndpoint.label} into ${targetEndpoint.label}?`,
initialValue: false,
});
if (p.isCancel(confirmed) || !confirmed) {
p.log.warn("Import cancelled.");
return;
}
const applied = await applyMergePlan({
sourceStorages,
targetStorage,
targetDb: targetHandle.db,
company,
plan: collected.plan,
});
if (applied.skippedMissingAttachmentObjects > 0) {
p.log.warn(
`Skipped ${applied.skippedMissingAttachmentObjects} attachments whose source files were missing from storage.`,
);
}
p.outro(
pc.green(
`Imported ${applied.insertedProjects} projects (${applied.insertedProjectWorkspaces} workspaces), ${applied.insertedIssues} issues, ${applied.insertedComments} comments, ${applied.insertedDocuments} documents (${applied.insertedDocumentRevisions} revisions, ${applied.mergedDocuments} merged), and ${applied.insertedAttachments} attachments into ${company.issuePrefix}.`,
),
);
} finally {
await targetHandle.stop();
await sourceHandle.stop();
}
}
async function backupWorktreeReseedTarget(input: {
targetConfig: PaperclipConfig;
targetPaths: WorktreeLocalPaths;
}): Promise<string> {View on GitHub (pinned to a7e689b3c3)
Solutions
- Verify the source instance's storage settings (storage mode, local dir, S3 bucket) — the import reads objects from the configured source storage.
- Restore or copy the missing object files back into source storage (attachment rows are already in the source DB).
- Re-run `paperclipai worktree import` — already-inserted rows are handled by the plan; the previously skipped attachments import once their files exist.
- If the count equals ALL attachments, the source storage config is almost certainly wrong — fix that first.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: every planned attachment object must exist in source storage
const missing: string[] = [];
for (const att of plan.attachments) {
const exists = await sourceStorage.exists(att.storageKey);
if (!exists) missing.push(att.storageKey);
}
if (missing.length) {
console.error(`Source storage is missing ${missing.length} attachment objects; fix storage before import.`);
} Prevention
- Keep the source storage backend (uploads dir / S3 bucket) with the database when copying instances.
- Review the import plan's attachment counts against skipped counts after apply; investigate any skip.
- Backup/verify S3 object continuity (lifecycle rules, versioning) before importing old companies.
- Re-run the import after restoring missing objects — planned rows not yet inserted will then land.
When it happens
Trigger: Source storage (local disk dir or S3 backend) missing object files for attachment rows: objects deleted out-of-band, source storage config pointing at the wrong location/bucket, partial copy of a data dir, S3 permission errors surfaced as missing keys.
Common situations: Copying a Paperclip data directory but forgetting the storage/uploads dir; S3 lifecycle rules deleting old objects; moving machines with an incomplete rsync.
Related errors
- Import cancelled.
- Import cancelled.
- Could not open your browser automatically. Open this URL man
- Reseed cancelled.
- Current checkout is the primary repo worktree. Pass --branch
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18).
Data as JSON: /api/errors/7e2b676fa496510d.
Report an issue: GitHub.