{"record":{"id":"a32e7c3f9cfdece6","repo":"can1357/oh-my-pi","slug":"invalid-ar-archive-missing-alignment-byte","errorCode":null,"errorMessage":"Invalid ar archive: missing alignment byte","messagePattern":"Invalid ar archive: missing alignment byte","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/unix-ar.ts","lineNumber":232,"sourceCode":"\t\tlet size = header.physicalSize;\n\t\tif (header.bsdNameLength !== undefined) {\n\t\t\tmetadataSize += header.bsdNameLength;\n\t\t\tassertIndexSize(metadataSize, options.limits, \"index\");\n\t\t\tconst nameBytes = readMemoryRange(bytes, payloadOffset, payloadOffset + header.bsdNameLength);\n\t\t\tconst decoded = decodeBsdName(nameBytes, options.limits);\n\t\t\tname = decoded.name;\n\t\t\tnameByteLength = decoded.byteLength;\n\t\t\tdataOffset += header.bsdNameLength;\n\t\t\tsize -= header.bsdNameLength;\n\t\t} else if (header.rawName === \"//\") {\n\t\t\tmetadataSize += header.physicalSize;\n\t\t\tassertIndexSize(metadataSize, options.limits, \"index\");\n\t\t\tlongNames = readMemoryRange(bytes, payloadOffset, payloadEnd);\n\t\t}\n\t\trecords.push({ name, nameByteLength, dataOffset, size, mtimeSeconds: header.mtimeSeconds, mode: header.mode });\n\t\tassertEntryCount(records.length, options.limits);\n\t\tposition = payloadEnd + (header.physicalSize & 1);\n\t\tif (position > bytes.byteLength) throw new ArchiveError(\"Invalid ar archive: missing alignment byte\");\n\t}\n\treturn materializeEntries(records, longNames, memoryByteSource(bytes), options);\n}\n\nasync function readExact(source: ByteSource, start: number, end: number, what: string): Promise<Uint8Array> {\n\tif (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start || end > source.size) {\n\t\tthrow new ArchiveError(`Invalid ar archive: truncated ${what}`);\n\t}\n\ttry {\n\t\tconst bytes = await source.read(start, end);\n\t\tif (bytes.byteLength !== end - start) throw new ArchiveError(`Invalid ar archive: truncated ${what}`);\n\t\treturn bytes;\n\t} catch (error) {\n\t\tif (error instanceof ArchiveError) throw error;\n\t\tthrow new ArchiveError(error instanceof Error ? error.message : String(error));\n\t}\n}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/unix-ar.ts#L214-L250","documentation":"ar members are padded to even offsets. After a member with an odd physical size, the parser must consume one alignment byte; if that byte would land past end-of-input, the archive is malformed and this error is thrown.","triggerScenarios":"An odd-sized member is the final member and the file ends immediately after its payload, so position = payloadEnd + 1 exceeds bytes.byteLength; or the single pad byte is missing entirely.","commonSituations":"Archives produced by non-conforming writers that skip the even-alignment pad byte; files truncated by exactly one byte; hand-processed archives where a member was replaced with odd-sized content.","solutions":["Rebuild the archive with GNU ar so odd-size members are padded.","If you control the writer, always emit a '\\n' pad byte after odd-sized payloads.","Compare byte length with a known-good copy to spot single-byte truncation.","Salvage with `ar x` (more tolerant) and repack."],"exampleFix":"// before: writer skips padding\nwrite(header); write(payload);\n// after: pad to even offset\nwrite(header); write(payload);\nif (payload.length % 2 === 1) writeByte(0x0a);","handlingStrategy":"validation","validationCode":"// writer-side guard: pad payloads to even length\nif (payload.byteLength % 2 === 1) chunks.push(new Uint8Array([0x0a]));","typeGuard":null,"tryCatchPattern":"try {\n  return await readUnixAr(source);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('missing alignment byte')) {\n    throw new Error('archive not even-byte aligned: likely written by a non-conforming tool');\n  }\n  throw err;\n}","preventionTips":["When writing ar members, always pad odd-sized payloads with a 0x0a byte.","Generate archives with GNU ar rather than hand-rolled writers.","After any byte-level archive surgery, re-check even alignment of every member.","Compare byte-for-byte with a GNU-ar-produced archive of the same content in tests."],"tags":["archive","ar-format","parsing","alignment"],"backgroundTag":"missing-ar-alignment-byte","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}