{"record":{"id":"0452f58a0112399a","repo":"can1357/oh-my-pi","slug":"invalid-arj-archive-header","errorCode":null,"errorMessage":"Invalid ARJ archive header","messagePattern":"Invalid ARJ archive header","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/arj.ts","lineNumber":239,"sourceCode":"\tconst body = bytes.subarray(4, 4 + size);\n\treturn body[0]! >= 30 && body[0]! <= size && body[6] === 2 && crc32(body) === u32(bytes, 4 + size);\n}\n\n/** Index an ARJ archive and lazily decode stored, static-Huffman, and fast-LZSS members. */\nexport const readArj: FormatReader = async (\n\tsource: ByteSource,\n\toptions: FormatReadOptions,\n): Promise<ArchiveIndexEntry[]> => {\n\tassertInMemorySize(source.size, options.limits);\n\tlet bytes: Uint8Array;\n\ttry {\n\t\tbytes = await readAllBytes(source);\n\t} catch (error) {\n\t\tif (error instanceof ArchiveError) throw error;\n\t\tthrow new ArchiveError(`Unable to read ARJ archive: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n\tif (bytes.byteLength !== source.size) throw new ArchiveError(\"Invalid ARJ archive: truncated data\");\n\tif (!sniffArj(bytes)) throw new ArchiveError(\"Invalid ARJ archive header\");\n\n\tconst main = parseArjBlock(bytes, 0, options);\n\tif (main.isEnd) throw new ArchiveError(\"Invalid ARJ archive: missing main header\");\n\tconst mainFirstHeaderSize = bytes[main.bodyStart]!;\n\tif (mainFirstHeaderSize < 30 || mainFirstHeaderSize > main.bodySize || bytes[main.bodyStart + 6] !== 2) {\n\t\tthrow new ArchiveError(\"Invalid ARJ main header\");\n\t}\n\tconst mainFlags = bytes[main.bodyStart + 4]!;\n\tif ((mainFlags & 0x01) !== 0) throw new ArchiveError(\"Encrypted ARJ archives are unsupported\");\n\tif ((mainFlags & 0x04) !== 0) throw new ArchiveError(\"Multi-volume ARJ archives are unsupported\");\n\n\tconst entries: ArchiveIndexEntry[] = [];\n\tlet offset = main.nextOffset;\n\tlet metadataSize = main.metadataSize;\n\tlet parsedCount = 0;\n\tfor (;;) {\n\t\tconst block = parseArjBlock(bytes, offset, options);\n\t\tmetadataSize += block.metadataSize;","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/arj.ts#L221-L257","documentation":"This ArchiveError is thrown when sniffArj rejects the input: the data does not begin with the ARJ magic bytes (0x60 0xEA) or the first header fails basic size/CRC checks. The file is simply not a valid ARJ archive as far as this reader can tell.","triggerScenarios":"Calling readArj(source, options) on a file that is not ARJ format (e.g. a ZIP, RAR, or text file), or an ARJ so corrupted that even the signature/header CRC is unreadable.","commonSituations":"Wrong file extension, renamed files, HTML error pages saved as .arj, zero-byte or placeholder files, SFX (self-extracting) executables with a leading EXE stub.","solutions":["Confirm the file is actually an ARJ archive (check magic bytes 0x60 0xEA at offset 0, or run `file archive.arj`).","If it is an SFX executable, strip the leading executable stub so the ARJ header is at offset 0.","Re-download the file — the header CRC may be damaged.","If it is another archive format, use that format's reader instead."],"exampleFix":"// before\nconst entries = await readArj(source, options);\n// after\nif (!sniffArj(bytes)) throw new Error(`${path} is not a valid ARJ archive (bad magic/header)`);\nconst entries = await readArj(source, options);","handlingStrategy":"validation","validationCode":"const head = new Uint8Array(2);\nawait fs.read(fd, head, 0, 2, 0);\nif (head[0] !== 0x60 || head[1] !== 0xea) {\n  throw new Error(`${path} is not an ARJ archive (bad magic)`);\n}","typeGuard":"function looksLikeArj(bytes: Uint8Array): boolean {\n  return bytes.byteLength >= 2 && bytes[0] === 0x60 && bytes[1] === 0xea;\n}","tryCatchPattern":"try {\n  const entries = await readArj(source, options);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.includes('archive header')) {\n    throw new Error(`${path} is not a valid ARJ archive; check the format`);\n  }\n  throw e;\n}","preventionTips":["Check magic bytes 0x60 0xEA before parsing","Use `file` or sniffArj to detect actual format instead of trusting extensions","For SFX executables, locate and slice off the leading stub first"],"tags":["archive","arj","format-detection","magic-bytes"],"backgroundTag":"invalid-archive-format","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}