schollz/croc · error · Error
Received more data than the advertised file size
Error message
Received more data than the advertised file size
What it means
Thrown inside DataReceiver.accept when the accumulated byte count for the active file exceeds the advertised size. The aligned-position check should prevent overshoot, so reaching this branch means total received bytes (counting every accepted chunk) went past file.size — e.g. overlapping-but-not-duplicate offsets after rounding, or a size advertisement smaller than the true file. It is a final consistency backstop that fails the transfer before finalize/verify.
Source
Thrown at web/src/protocol/client.ts:634
if (active.received.has(position)) throw new Error("Received a duplicate file chunk");
if (
position < 0 ||
position % CHUNK_SIZE !== 0 ||
bytes.byteLength === 0 ||
bytes.byteLength > CHUNK_SIZE ||
position + bytes.byteLength > active.file.size
) {
throw new Error("Received a file chunk outside the advertised file size");
}
active.received.add(position);
await active.sink.writeAt(position, bytes);
active.bytes += bytes.byteLength;
active.progress(active.bytes);
if (active.bytes === active.file.size) {
this.active = undefined;
active.resolve();
} else if (active.bytes > active.file.size) {
throw new Error("Received more data than the advertised file size");
}
});
active.queue.catch((error) => {
if (this.active === active) this.active = undefined;
active.reject(error instanceof Error ? error : new Error(String(error)));
});
return active.queue;
}
}
export async function receiveFiles(options: {
secret: string;
settings: TransferSettings;
callbacks: ReceiveCallbacks;
signal?: AbortSignal;
}) {
const { secret, settings, callbacks, signal } = options;
validateSecret(secret);View on GitHub (pinned to e25f1bdc04)
Solutions
- Guarantee the file is immutable from hashing through streaming; snapshot large/active files before prepareFiles
- Cross-check prepared.size against the actual bytes sliced in sendFileData in tests
- Treat this error as evidence of sender-side state drift — re-prepare files and restart the transfer
- If it reproduces deterministically at file end, log chunkCount, final position, and advertised size to find the off-by-one
Defensive patterns
Strategy: validation
Validate before calling
// Sender-side: snapshot mutable files before hashing so size cannot drift const snapshot = await file.slice(0, file.size).arrayBuffer(); // then hash/stream from the snapshot
Try / catch
catch (e) {
if (e instanceof Error && e.message === "Received more data than the advertised file size") {
// sender streamed past its own advertisement: re-prepare files and restart
}
throw e;
} Prevention
- Do not transfer files that are actively being written; copy them first and transfer the copy
- Re-run prepareFiles whenever the source File objects may have changed
- On this error always restart from prepareFiles — partial state is unreliable
When it happens
Trigger: Sender advertises size N in fileinfo but streams more than N bytes (file grew after hashing); rounding in chunkCount math (Math.ceil(size/CHUNK_SIZE)) sending a full final chunk where a partial one was expected and position checks passed; a peer sending an extra chunk past the final aligned offset with distinct positions.
Common situations: The sender's file is appended to (log file, download in progress) between prepareFiles and the transfer loop; inconsistent size fields between senderInfo and sendFileData; adversarial sender probing the receiver's bounds checks.
Related errors
- Received a file chunk outside the advertised file size
- Received an invalid file chunk
- Received a file position that is too large
- Received a duplicate file chunk
- Code must be at least 6 characters
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/605e249b5ea46046.
Report an issue: GitHub.