{"record":{"id":"712f78b2d76c96a1","repo":"can1357/oh-my-pi","slug":"unable-to-read-arj-archive-error-instanceof-err","errorCode":null,"errorMessage":"Unable to read ARJ archive: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Unable to read ARJ archive: (.+?)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/arj.ts","lineNumber":236,"sourceCode":"\tif (bytes.byteLength < 34 || bytes[0] !== ARJ_SIGNATURE_0 || bytes[1] !== ARJ_SIGNATURE_1) return false;\n\tconst size = u16(bytes, 2);\n\tif (size < 30 || size > ARJ_MAX_BASIC_HEADER || bytes.byteLength < size + 8) return false;\n\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;","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/arj.ts#L218-L254","documentation":"This wrapper ArchiveError is thrown by readArj when reading the archive's bytes from the ByteSource fails with a non-ArchiveError error (I/O failure, permission denied, stream error). The original error message is embedded so the underlying cause is preserved.","triggerScenarios":"Calling readArj(source, options) where readAllBytes(source) rejects with a filesystem or network error — e.g. the file was deleted mid-read, read permission is missing, or a remote stream errored.","commonSituations":"Files on unmounted/network drives, permissions changed between stat and read, deleted temp files, storage device errors.","solutions":["Check that the file exists and is readable at the given path before calling readArj.","Inspect the wrapped message (the cause) to identify the underlying I/O error.","Re-mount or restore access to the storage location and retry.","Copy the archive to a local, stable path and read from there."],"exampleFix":"// before\nconst entries = await readArj({ path, size: stat.size }, options);\n// after\ntry {\n  const entries = await readArj({ path, size: stat.size }, options);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.startsWith('Unable to read ARJ archive')) {\n    throw new Error(`cannot access ${path}: ${e.message}`);\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"const stat = await fs.stat(path);\nif (!stat.isFile()) throw new Error(`${path} is not a regular file`);\nawait fs.access(path, fs.constants.R_OK);","typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readArj(source, options);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.startsWith('Unable to read ARJ archive')) {\n    // underlying I/O error embedded in message; check file existence/permissions\n  } else throw e;\n}","preventionTips":["Stat and permission-check the file before reading","Avoid reading from volatile locations (temp dirs, network shares) directly","Copy remote archives to local storage before parsing"],"tags":["io","filesystem","archive","arj"],"backgroundTag":"file-read-failure","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}