can1357/oh-my-pi · error · ArchiveError
Invalid CPIO archive: truncated ${what}
Error message
Invalid CPIO archive: truncated ${what} What it means
requireRange validates that a requested byte range [start,end) lies within the CPIO buffer; when it does not, the archive is reported as 'truncated <what>' (which field, e.g. 'ino field' or 'magic field'). It is the bounds-check used while parsing header fields and entries, so any header that runs past EOF produces this error.
Source
Thrown at packages/utils/src/ar/cpio.ts:100
let checksum = 0;
for (const byte of bytes) checksum = (checksum + byte) >>> 0;
return checksum;
}
function align(value: number, alignment: number): number {
const remainder = value % alignment;
return remainder === 0 ? value : value + alignment - remainder;
}
function requireRange(bytes: Uint8Array, start: number, end: number, what: string): void {
if (
!Number.isSafeInteger(start) ||
!Number.isSafeInteger(end) ||
start < 0 ||
end < start ||
end > bytes.byteLength
) {
throw new ArchiveError(`Invalid CPIO archive: truncated ${what}`);
}
}
function parseDigits(bytes: Uint8Array, offset: number, length: number, radix: 8 | 16, field: string): number {
requireRange(bytes, offset, offset + length, `${field} field`);
let value = 0;
for (let index = offset; index < offset + length; index++) {
const code = bytes[index]!;
let digit: number;
if (code >= 0x30 && code <= 0x39) digit = code - 0x30;
else if (radix === 16 && code >= 0x41 && code <= 0x46) digit = code - 0x41 + 10;
else if (radix === 16 && code >= 0x61 && code <= 0x66) digit = code - 0x61 + 10;
else throw new ArchiveError(`Invalid CPIO archive: ${field} is not a valid base-${radix} number`);
if (digit >= radix) throw new ArchiveError(`Invalid CPIO archive: ${field} is not a valid base-${radix} number`);
value = value * radix + digit;
}
if (!Number.isSafeInteger(value)) throw new ArchiveError(`Invalid CPIO archive: ${field} is too large`);
return value;View on GitHub (pinned to 9690622007)
Solutions
- Re-acquire a complete archive and retry
- Verify the cpio parses with the system tool: cpio -it < file
- Check the offset/base you are parsing from if the cpio is embedded in a larger file
- Confirm the format matches what the parser expects (odc vs newc)
Example fix
// before: wrong offset into container
const entries = await readCpioEntriesFromBuffer(container.subarray( guessedOffset ));
// after: locate the real cpio start (magic '070701' for newc)
const magicIndex = container.indexOf(Buffer.from('070701', 'ascii'));
const entries = await readCpioEntriesFromBuffer(container.subarray(magicIndex)); Defensive patterns
Strategy: validation
Validate before calling
function looksLikeCpio(bytes: Uint8Array): boolean {
const magic = Buffer.from(bytes.subarray(0, 6)).toString('ascii');
return magic === '070701' || magic === '070702' || magic === '070707';
}
if (!looksLikeCpio(bytes) || bytes.byteLength < 110) throw new Error('not a (complete) cpio archive'); Type guard
function looksLikeCpio(bytes: Uint8Array): boolean {
const magic = Buffer.from(bytes.subarray(0, 6)).toString('ascii');
return magic === '070701' || magic === '070702' || magic === '070707';
} Try / catch
try {
const entries = await readCpioEntriesFromBuffer(bytes);
} catch (err) {
if (err instanceof ArchiveError && /^Invalid CPIO archive: truncated/.test(err.message)) {
// message names which field ran past EOF; usually a truncated file or wrong offset
throw new Error(`cpio unreadable (${err.message}); re-acquire or fix parse offset`);
} else throw err;
} Prevention
- Check the magic bytes before parsing
- When cpio is embedded, derive the start offset from the magic string, never a guess
- Confirm archive completeness (size or digest) before parsing
When it happens
Trigger: Calling readCpioEntriesFromBuffer on truncated data; header fields extending past end-of-buffer due to a corrupted size/count field; parsing at a wrong offset inside a larger container so field reads run past the buffer end.
Common situations: Partial initramfs/cpio downloads; wrong offset when extracting a cpio embedded in a firmware image; format confusion (parsing an 'odc' file as 'newc' with wrong field widths); zero-length or empty cpio files.
Related errors
- CPIO member '${memberPath}' is truncated
- Invalid ARJ archive: truncated data
- Invalid CAB archive: member '${memberPath}' is outside its f
- Invalid XZ stream: truncated integer
- Invalid XZ stream: truncated variable-length integer
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/870f46bc80514c6e.
Report an issue: GitHub.