schollz/croc · error

Storage service created ${acceptedDownloads} downloads inste

Error message

Storage service created ${acceptedDownloads} downloads instead of ${downloads}

What it means

Even when X-Croc-Downloads parses, the client requires the granted count to equal the requested downloads value. If the server silently clamps (e.g., requested 5, granted 1) or the header defaults to 1 while the client asked for more, creation aborts: the sender would otherwise hand out a share whose actual download budget differs from what was promised.

Source

Thrown at web/src/protocol/stored.ts:454

    uploadExpiresAt: string;
    chunkSize: number;
  };
  if (created.chunkSize !== storedChunkSize) {
    throw new Error(
      `Storage service returned unsupported chunk size ${created.chunkSize}`,
    );
  }
  if (!isCapability(created.uploadToken)) {
    throw new Error("Storage service returned an invalid upload capability");
  }
  const downloadsHeader = response.headers.get("X-Croc-Downloads");
  const acceptedDownloads =
    downloadsHeader === null ? 1 : Number(downloadsHeader);
  if (!Number.isSafeInteger(acceptedDownloads) || acceptedDownloads < 1) {
    throw new Error("Storage service returned an invalid download count");
  }
  if (acceptedDownloads !== downloads) {
    throw new Error(
      `Storage service created ${acceptedDownloads} downloads instead of ${downloads}`,
    );
  }
  return {
    share: validateShare({
      origin: window.location.origin,
      id: created.id,
      key,
    }),
    uploadToken: created.uploadToken,
  };
}

async function uploadStoredManifest(
  plan: StoredUploadPlan,
  created: CreatedStoredUpload,
  settings: StoredSettings,
  callbacks: StoredUploadCallbacks,

View on GitHub (pinned to e25f1bdc04)

Solutions

  1. Request a downloads count within the server's limit — align settings.maxDownloads on the client with the server's actual cap
  2. If the header is optional on your server version, only request the default (omit downloads) so both sides agree on 1
  3. Update the storage service so it either honors the requested count or rejects the request explicitly with 4xx
Defensive patterns

Strategy: validation

Validate before calling

const safeDownloads = Math.min(requestedDownloads, settings.maxDownloads);
if (!Number.isSafeInteger(safeDownloads) || safeDownloads < 1) { throw new Error("Invalid downloads setting"); }

Try / catch

try { return await uploadStoredFiles({ ..., downloads }); } catch (e) { if (e instanceof Error && e.message.includes("instead of")) { return uploadStoredFiles({ ..., downloads: 1 }); } throw e; }

Prevention

When it happens

Trigger: uploadStoredFiles({downloads: 5}) against a server that caps or ignores the field and echoes a different X-Croc-Downloads; also when the header is absent (defaults to 1) but downloads !== 1 was requested.

Common situations: Server-side maxDownloads lower than the client UI allowed (settings skew); older servers that never implemented multi-download and always grant 1; operators changing limits without refreshing client settings.

Related errors


AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15). Data as JSON: /api/errors/e3e8ce33c3f30533. Report an issue: GitHub.