schollz/croc · error

Stored transfers can allow at most ${settings.maxDownloads}

Error message

Stored transfers can allow at most ${settings.maxDownloads} downloads

What it means

Thrown by uploadStoredFiles() (stored.ts:578) when the requested `downloads` count exceeds the ceiling the storage service advertised in settings.maxDownloads. The settings object comes from the store runtime (App.tsx computes `storeRuntime.maxDownloads || 1`), so the limit varies per deployment and defaults to 1.

Source

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

  settings: StoredSettings;
  downloads?: number;
  expiresSeconds?: number;
  callbacks?: StoredUploadCallbacks;
  signal?: AbortSignal;
}) {
  const {
    files,
    settings,
    downloads = 1,
    expiresSeconds = 24 * 60 * 60,
    callbacks = {},
    signal,
  } = options;
  if (!Number.isSafeInteger(downloads) || downloads < 1) {
    throw new Error("Stored-transfer downloads must be a positive integer");
  }
  if (downloads > settings.maxDownloads) {
    throw new Error(
      `Stored transfers can allow at most ${settings.maxDownloads} downloads`,
    );
  }
  if (
    !Number.isSafeInteger(expiresSeconds) ||
    expiresSeconds < 60 ||
    expiresSeconds > 9_223_372_036
  ) {
    throw new Error(
      "Stored-transfer expiration must be a whole number of seconds of at least one minute",
    );
  }
  if (
    settings.maxExpiresSeconds > 0 &&
    expiresSeconds > settings.maxExpiresSeconds
  ) {
    throw new Error(
      `Stored transfers can expire after at most ${settings.maxExpiresSeconds} seconds`,

View on GitHub (pinned to e25f1bdc04)

Solutions

  1. Clamp the request: Math.min(requested, settings.maxDownloads)
  2. Render the UI picker's max from settings.maxDownloads so users cannot over-request
  3. Fetch settings from the live service configuration instead of hardcoding

Example fix

// before
await uploadStoredFiles({ files, settings, downloads: userChoice });

// after
const downloads = Math.min(userChoice, settings.maxDownloads);
await uploadStoredFiles({ files, settings, downloads });
Defensive patterns

Strategy: validation

Validate before calling

const downloads = Math.min(Math.max(1, requested), settings.maxDownloads);

Type guard

function withinDownloadLimit(downloads: number, s: StoredSettings): boolean {
  return downloads >= 1 && downloads <= s.maxDownloads;
}

Try / catch

try { await uploadStoredFiles(opts); } catch (e) { if (e instanceof Error && e.message.startsWith('Stored transfers can allow at most')) { opts.downloads = settings.maxDownloads; return uploadStoredFiles(opts); } throw e; }

Prevention

When it happens

Trigger: Calling uploadStoredFiles with downloads > settings.maxDownloads, e.g. downloads: 10 when the service configures maxDownloads: 3. Happens when the UI allows more downloads than the server permits or the settings object is hardcoded/stale.

Common situations: Server operator lowered maxDownloads after the UI shipped; reusing a settings object across dev/prod environments; tests running against settings fixtures with a different cap than production.

Related errors


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