can1357/oh-my-pi · error · ArchiveError

CPIO member '${memberPath}' has an inconsistent declared siz

Error message

CPIO member '${memberPath}' has an inconsistent declared size

What it means

Thrown by a CPIO member's read() when the caller requests a size different from the size declared in the member's header. The library requires the request to exactly match the header-declared size so offsets and CRC checks stay consistent.

Source

Thrown at packages/utils/src/ar/cpio.ts:67

	resolveTarget: boolean;
}

class CpioMemberSource implements MemberSource {
	readonly #bytes: Uint8Array;
	readonly #offset: number;
	readonly #size: number;
	readonly #checksum?: number;

	constructor(bytes: Uint8Array, offset: number, size: number, checksum?: number) {
		this.#bytes = bytes;
		this.#offset = offset;
		this.#size = size;
		this.#checksum = checksum;
	}

	async read(size: number, memberPath: string): Promise<Uint8Array> {
		if (size !== this.#size) {
			throw new ArchiveError(`CPIO member '${memberPath}' has an inconsistent declared size`);
		}
		const end = this.#offset + this.#size;
		if (end > this.#bytes.byteLength) {
			throw new ArchiveError(`CPIO member '${memberPath}' is truncated`);
		}
		const bytes = this.#bytes.subarray(this.#offset, end);
		if (this.#checksum !== undefined && checksumBytes(bytes) !== this.#checksum) {
			throw new ArchiveError(`CPIO member '${memberPath}' has an invalid CRC checksum`);
		}
		return bytes;
	}
}

function checksumBytes(bytes: Uint8Array): number {
	let checksum = 0;
	for (const byte of bytes) checksum = (checksum + byte) >>> 0;
	return checksum;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass exactly the size parsed from the member's own header (the value returned with the entry metadata)
  2. Fix the header parser if it produces a wrong size (check field widths/radix for the archive format: odc octal vs newc hex)
  3. If you need only part of the data, read the full size then slice the returned Uint8Array

Example fix

// before
const data = await member.read(someOtherSize, entry.name);
// after
const data = await member.read(entry.size, entry.name);
Defensive patterns

Strategy: validation

Validate before calling

// pass the header-declared size exactly
if (requestedSize !== entry.size) {
  throw new TypeError(`size mismatch for ${entry.name}: requested ${requestedSize}, header says ${entry.size}`);
}
const data = await member.read(entry.size, entry.name);

Try / catch

try {
  const data = await member.read(entry.size, entry.name);
} catch (err) {
  if (err instanceof ArchiveError && /inconsistent declared size/.test(err.message)) {
    // fix the size you passed; read full member then slice
  } else throw err;
}

Prevention

When it happens

Trigger: Calling member.read(size, path) where size differs from the header's filesize field — e.g. passing a buffer length, an estimated size, or reading the same member with a wrong constant.

Common situations: Hand-rolled CPIO parsers passing accumulated byte counts instead of header sizes; copy-paste errors reusing another member's size; new-c archive header parsing mistakes producing a different size value.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/02bfd0a76ed6a653. Report an issue: GitHub.