paperclipai/paperclip · warning · Error
This exact package was already imported by a completed trans
Error message
This exact package was already imported by a completed transfer. Re-export the package to import it again.
What it means
Thrown by uploadCompanyImportTransfer when the server reports created.alreadyCompleted === true. The server content-addresss transfers; if this exact zip already finished an apply, its spooled parts have been deleted, so the parts cannot be re-uploaded and the apply cannot be re-run. The fix is to produce a fresh package.
Source
Thrown at cli/src/commands/client/company.ts:1163
* with the transfer id once the server holds every part.
*/
export async function uploadCompanyImportTransfer(
api: Pick<PaperclipApiClient, "post" | "putRaw">,
zipBytes: Uint8Array,
opts: { onProgress?: (progress: ImportTransferUploadProgress) => void } = {},
): Promise<string> {
const manifest = buildImportTransferManifest(zipBytes);
const created = await api.post<CompanyImportTransferCreated>(
`/api/companies${COMPANY_IMPORT_TRANSFERS_ROUTE_PATH}`,
manifest,
);
if (!created) {
throw new Error("Import transfer declaration returned no data.");
}
if (created.alreadyCompleted) {
// The server keys transfers by content, and this exact zip already
// finished an apply — its spooled parts are gone, so it cannot re-run.
throw new Error(
"This exact package was already imported by a completed transfer. Re-export the package to import it again.",
);
}
const missing = new Set(created.missingParts);
let uploadedParts = manifest.parts.length - missing.size;
let uploadedBytes = manifest.parts.reduce(
(sum, part) => (missing.has(part.index) ? sum : sum + part.byteSize),
0,
);
for (const part of manifest.parts) {
if (!missing.has(part.index)) continue;
const offset = part.index * manifest.partSizeBytes;
const bytes = zipBytes.subarray(offset, offset + part.byteSize);
let lastError: unknown = null;
let uploaded = false;
for (let attempt = 0; attempt < IMPORT_TRANSFER_PART_ATTEMPTS && !uploaded; attempt += 1) {
try {
await api.putRaw(View on GitHub (pinned to 67001ec6eb)
Solutions
- Re-export the source to produce a new zip (content hash will differ if anything changed) and import that.
- If the source is unchanged, the previous import already succeeded — verify the company state instead of re-importing.
- Add a tiny non-functional change (a timestamp/manifest entry) to force a different content hash if you truly need to re-run.
- Check the import history on the server to confirm the prior apply outcome before re-exporting.
Example fix
# before (reusing stale zip) paperclipai company import nightly-backup-2024-01-01.zip --yes # after (fresh export first) paperclipai company export --company cmp_abc --out fresh.zip paperclipai company import fresh.zip --yes
Defensive patterns
Strategy: try-catch
Try / catch
try {
await uploadCompanyImportTransfer(api, zipBytes);
} catch (err) {
if (err instanceof Error && /already imported by a completed transfer/.test(err.message)) {
console.warn("Package already imported. Re-export the source to re-run, or verify state on the server.");
return;
}
throw err;
} Prevention
- Treat the prior apply as authoritative when content is unchanged.
- Re-export packages fresh for each import run rather than reusing zips.
- Track apply outcomes in your orchestration layer to skip duplicate uploads.
When it happens
Trigger: Re-running an import with the exact same zip file (byte-identical) after a previous apply completed. Reusing a cached .zip from an earlier export. A backup routine that re-uploads the same nightly artifact twice. Any idempotent retry of an apply that already succeeded.
Common situations: An operator re-runs a failed-looking import that actually completed. CI uploads the same artifact twice. A user double-clicks the apply button. A scheduled job produces a deterministic zip and runs more than once against the same content.
Related errors
- Import transfer declaration returned no data.
- Existing-company imports require a companyId to resolve the
- Applying a company import with --json requires --yes. Use --
- Applying a company import from a non-interactive terminal re
- GitHub source must be a GitHub or GitHub Enterprise URL, or
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/8e67a3069cbc9ae9.
Report an issue: GitHub.