{"record":{"id":"02bfd0a76ed6a653","repo":"can1357/oh-my-pi","slug":"cpio-member-memberpath-has-an-inconsistent-de","errorCode":null,"errorMessage":"CPIO member '${memberPath}' has an inconsistent declared size","messagePattern":"CPIO member '(.+?)' has an inconsistent declared size","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cpio.ts","lineNumber":67,"sourceCode":"\tresolveTarget: boolean;\n}\n\nclass CpioMemberSource implements MemberSource {\n\treadonly #bytes: Uint8Array;\n\treadonly #offset: number;\n\treadonly #size: number;\n\treadonly #checksum?: number;\n\n\tconstructor(bytes: Uint8Array, offset: number, size: number, checksum?: number) {\n\t\tthis.#bytes = bytes;\n\t\tthis.#offset = offset;\n\t\tthis.#size = size;\n\t\tthis.#checksum = checksum;\n\t}\n\n\tasync read(size: number, memberPath: string): Promise<Uint8Array> {\n\t\tif (size !== this.#size) {\n\t\t\tthrow new ArchiveError(`CPIO member '${memberPath}' has an inconsistent declared size`);\n\t\t}\n\t\tconst end = this.#offset + this.#size;\n\t\tif (end > this.#bytes.byteLength) {\n\t\t\tthrow new ArchiveError(`CPIO member '${memberPath}' is truncated`);\n\t\t}\n\t\tconst bytes = this.#bytes.subarray(this.#offset, end);\n\t\tif (this.#checksum !== undefined && checksumBytes(bytes) !== this.#checksum) {\n\t\t\tthrow new ArchiveError(`CPIO member '${memberPath}' has an invalid CRC checksum`);\n\t\t}\n\t\treturn bytes;\n\t}\n}\n\nfunction checksumBytes(bytes: Uint8Array): number {\n\tlet checksum = 0;\n\tfor (const byte of bytes) checksum = (checksum + byte) >>> 0;\n\treturn checksum;\n}","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cpio.ts#L49-L85","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass exactly the size parsed from the member's own header (the value returned with the entry metadata)","Fix the header parser if it produces a wrong size (check field widths/radix for the archive format: odc octal vs newc hex)","If you need only part of the data, read the full size then slice the returned Uint8Array"],"exampleFix":"// before\nconst data = await member.read(someOtherSize, entry.name);\n// after\nconst data = await member.read(entry.size, entry.name);","handlingStrategy":"validation","validationCode":"// pass the header-declared size exactly\nif (requestedSize !== entry.size) {\n  throw new TypeError(`size mismatch for ${entry.name}: requested ${requestedSize}, header says ${entry.size}`);\n}\nconst data = await member.read(entry.size, entry.name);","typeGuard":null,"tryCatchPattern":"try {\n  const data = await member.read(entry.size, entry.name);\n} catch (err) {\n  if (err instanceof ArchiveError && /inconsistent declared size/.test(err.message)) {\n    // fix the size you passed; read full member then slice\n  } else throw err;\n}","preventionTips":["Always read with the size returned by the parser for that member","Never reuse one member's size for another","Need a subset? Read the full member and subarray() the result"],"tags":["cpio","archive","validation","arguments"],"backgroundTag":"archive-member-size-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}