paperclipai/paperclip · error · Error

Import transfer declaration returned no data.

Error message

Import transfer declaration returned no data.

What it means

Thrown by uploadCompanyImportTransfer when the POST to declare the transfer returns a falsy body. The server contract for /api/companies/.../imports/transfers requires a JSON object describing the transfer; an empty/204/null response means the API surface is broken or the client/server versions are out of sync.

Source

Thrown at cli/src/commands/client/company.ts:1158

}

/**
 * Declare (or resume) the transfer for these zip bytes and upload every part
 * the server reports missing, sequentially with per-part retries. Resolves
 * 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);

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Verify the server is running a version that supports the imports/transfers route and returns the expected JSON.
  2. Check the API base URL and any proxy in front of it is not stripping response bodies.
  3. Update both server and CLI to compatible versions.
  4. Inspect the raw HTTP response with curl against /api/companies/.../imports/transfers to confirm the server emits a body.
  5. If this is a test double, ensure the mocked post returns a valid CompanyImportTransferCreated object.

Example fix

// before (mock returns nothing)
const api = { post: async () => undefined, putRaw: async () => {} };
await uploadCompanyImportTransfer(api, zipBytes);
// after
const created = { transferId: "tfr_1", missingParts: [0,1], alreadyCompleted: false };
const api = { post: async () => created, putRaw: async () => {} };
await uploadCompanyImportTransfer(api, zipBytes);
Defensive patterns

Strategy: try-catch

Type guard

function isValidTransferCreated(v: unknown): v is { transferId: string; missingParts: number[]; alreadyCompleted: boolean } {
  return (
    typeof v === "object" && v !== null &&
    typeof (v as any).transferId === "string" &&
    Array.isArray((v as any).missingParts) &&
    typeof (v as any).alreadyCompleted === "boolean"
  );
}

Try / catch

try {
  const transferId = await uploadCompanyImportTransfer(api, zipBytes);
} catch (err) {
  if (err instanceof Error && /returned no data/.test(err.message)) {
    // server contract broken: surface to operator, check versions/proxy
    throw new Error(`Import transfer endpoint returned empty body. Verify server version and proxy. Cause: ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: The PaperclipApiClient.post call resolves to undefined (e.g. a 204 No Content, a proxy that strips the body, a server bug returning empty, or a version mismatch where the route exists but the response shape changed). Network middleware that replaces the body with null.

Common situations: Talking to an older server that does not implement the chunked transfer endpoint. A reverse proxy or gateway swallowing the response body. A mock client in tests that forgets to return the created object. Client/server version skew after an upgrade.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/7d9293dda3ae7a7c. Report an issue: GitHub.