schollz/croc · error · Error
Invalid file size for ${file.n ?? "unnamed file"}
Error message
Invalid file size for ${file.n ?? "unnamed file"} What it means
finiteSize() validates each offered file's size field: it defaults missing sizes to 0, then requires Number.isSafeInteger and >= 0. Floats, negatives, NaN, Infinity, or integers beyond 2^53-1 fail, because such sizes cannot be tracked or summed reliably in JavaScript.
Source
Thrown at web/src/protocol/metadata.ts:58
throw new Error(`Remote filename must be a basename: ${nameValue}`);
}
const name = nameSegments[0];
if (!name) throw new Error("Remote filename is empty");
const path = folder === "." ? name : `${folder}/${name}`;
return { folder, name, path };
}
export function normalizeOutgoingFileName(value: string) {
// Go's unicode.IsPrint accepts ASCII space but rejects the other Unicode
// separator characters commonly inserted into filenames by macOS.
const compatible = value.replace(/\p{Z}+/gu, " ");
return normalizeFilePath(".", compatible).name;
}
function finiteSize(file: WireFileInfo) {
const size = file.s ?? 0;
if (!Number.isSafeInteger(size) || size < 0) {
throw new Error(`Invalid file size for ${file.n ?? "unnamed file"}`);
}
return size;
}
export function validateSenderInfo(info: SenderInfoWire): TransferOffer {
if (info.SendingText) throw new Error("Text transfers are not supported yet");
if (info.HashAlgorithm && info.HashAlgorithm !== "xxhash") {
throw new Error(`Hash algorithm "${info.HashAlgorithm}" is not supported`);
}
const destinations = new Set<string>();
const files: OfferedFile[] = [];
let totalSize = 0;
for (const wire of info.FilesToTransfer ?? []) {
if (wire.sy) throw new Error("Symlink transfers are not supported in the browser");
const normalized = normalizeFilePath(wire.fr ?? ".", wire.n ?? "");
if (destinations.has(normalized.path)) {
throw new Error(`Duplicate destination path: ${normalized.path}`);View on GitHub (pinned to e25f1bdc04)
Solutions
- Send sizes as non-negative integers within the safe range in the offer.
- As a receiver, refuse transfers with malformed size metadata — do not clamp or default unknown sizes.
- In tests, include 's' (or accept the 0 default) for every file fixture.
Example fix
// before (fixture)
{ n: "a.bin", s: 1e19 }
// after
{ n: "a.bin", s: 1024 } Defensive patterns
Strategy: type-guard
Validate before calling
function isSafeFileSize(size: number | undefined): boolean {
const s = size ?? 0;
return Number.isSafeInteger(s) && s >= 0;
} Type guard
function isWireFileSize(file: { s?: number }): file is { s?: number } & { s: number } {
const s = file.s ?? 0;
return Number.isSafeInteger(s) && s >= 0;
} Try / catch
try {
const offer = validateSenderInfo(info);
} catch (error) {
if (error instanceof Error && error.message.startsWith("Invalid file size")) {
rejectOffer("malformed size metadata");
return;
}
throw error;
} Prevention
- Emit sizes as non-negative safe integers in offers.
- Reject NaN/Infinity/negative size metadata rather than defaulting it.
- Cap accepted per-file sizes in receiving services so hostile metadata fails early with a clear message.
When it happens
Trigger: validateSenderInfo() processes a WireFileInfo whose 's' is fractional (0.5), negative, NaN/Infinity (e.g. parsed from 'NaN' in JSON), or larger than Number.MAX_SAFE_INTEGER (~9 PB).
Common situations: Hostile peer declaring a negative or astronomical size to break progress math; a peer encoding sizes as floats; hand-built test offers forgetting 's'; JSON containing exponent-notation sizes that parse to Infinity.
Related errors
- Transfer size is too large
- Remote filename is empty
- Duplicate destination path: ${normalized.path}
- Duplicate destination path: ${folder}
- Code must be at least 6 characters
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/d92b58d6e2fbc5ae.
Report an issue: GitHub.