can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: size changed while extracting '${member
Error message
Invalid CAB archive: size changed while extracting '${memberPath}' What it means
Thrown by CabMemberSource.read when the size argument passed at extraction time differs from the size the CFFILE entry declared when the archive was indexed. The archive index is built once with fixed per-member sizes; this is an internal consistency check indicating the member source is being driven with a stale or mismatched size.
Source
Thrown at packages/utils/src/ar/cab.ts:227
);
}
output.set(decoded, outputPosition);
outputPosition += decoded.byteLength;
position = payloadEnd;
}
return output;
}
}
class CabMemberSource implements MemberSource {
readonly #folder: CabFolder;
readonly #offset: number;
readonly #declaredSize: number;
constructor(folder: CabFolder, offset: number, size: number) {
this.#folder = folder;
this.#offset = offset;
this.#declaredSize = size;
}
async read(size: number, memberPath: string): Promise<Uint8Array> {
if (size !== this.#declaredSize) {
throw new ArchiveError(`Invalid CAB archive: size changed while extracting '${memberPath}'`);
}
const folder = await this.#folder.readAll();
const end = this.#offset + size;
if (!Number.isSafeInteger(end) || this.#offset < 0 || end > folder.byteLength) {
throw new ArchiveError(`Invalid CAB archive: member '${memberPath}' is outside its folder data`);
}
return folder.slice(this.#offset, end);
}
}
async function readCabArchive(source: ByteSource, options: Parameters<FormatReader>[1]): Promise<ArchiveIndexEntry[]> {
if (source.size < FIXED_HEADER_SIZE) throw new ArchiveError("Invalid CAB archive: truncated CFHEADER");
const fixed = await readExact(source, 0, FIXED_HEADER_SIZE);View on GitHub (pinned to 9690622007)
Solutions
- Always pass the entry.size from the same ArchiveIndexEntry that produced the member source
- Do not cache ArchiveIndexEntry/member sources across archive reads; re-index per extraction
- Check for code that mutates entry.size or passes a computed size instead of the declared one
- If your extraction pipeline legitimately knows a different size, re-read the archive so the index matches
Example fix
// before const size = files[name]; // stale map from a previous run const data = await entry.storage.source.read(size, name); // after const data = await entry.storage.source.read(entry.size, name);
Defensive patterns
Strategy: type-guard
Validate before calling
// before reading, ensure the size comes from the same indexed entry
function canRead(entry: ArchiveIndexEntry, size: number): boolean {
return entry.storage?.type === 'member' && size === entry.size;
} Type guard
function isMemberEntry(entry: ArchiveIndexEntry): entry is ArchiveIndexEntry & { storage: { type: 'member'; source: MemberSource } } {
return entry.storage?.type === 'member';
} Try / catch
try {
const data = await entry.storage.source.read(entry.size, entry.path);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('size changed while extracting'))
throw new Error('Size used for read does not match the indexed entry — re-index the archive.');
throw err;
} Prevention
- Always pass entry.size from the same index entry you got the source from
- Never cache index entries across archive re-reads
- Do not mutate entry.size or compute your own size before read
When it happens
Trigger: Calling a member's read/storage path with a size different from the entry.size returned in the ArchiveIndexEntry — e.g. using an entry from a previous index run against a new archive, or hand-modifying the size before reading.
Common situations: Caching ArchiveIndexEntry objects across archive re-reads; passing entry.size to a different member's source; custom extraction code that overrides the declared size.
Related errors
- Invalid CAB archive: metadata range is out of bounds
- Unable to read CAB archive: ${error instanceof Error ? error
- Invalid CAB archive: truncated data
- Invalid CAB archive: file name is not valid UTF-8
- Invalid CAB archive: file has an invalid DOS timestamp
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c8b10d21614371eb.
Report an issue: GitHub.