{"record":{"id":"9b95c2964cde2b04","repo":"can1357/oh-my-pi","slug":"failed-to-read-tar-archive","errorCode":null,"errorMessage":"Failed to read tar archive","messagePattern":"Failed to read tar archive","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/tar.ts","lineNumber":586,"sourceCode":"\t\t\tmtimeMs,\n\t\t\tmode,\n\t\t\tstorage: { type: \"member\", source: new TarMemberSource(buffer, dataOffset, sparse) },\n\t\t});\n\t}\n\tif (!sawTerminator) throw new ArchiveError(\"Not a valid tar archive: missing terminating zero block\");\n\tresolvePendingLinks(entries, pendingLinks, limits);\n\treturn [...entries.values()];\n}\n\n/** Read and index a tar source after one bounded whole-stream read. */\nexport const readTar: FormatReader = async (source, options) => {\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(error instanceof Error ? error.message : \"Failed to read tar archive\");\n\t}\n\tif (bytes.byteLength !== source.size) throw new ArchiveError(\"Invalid archive: truncated data\");\n\treturn readTarEntriesFromBuffer(bytes, options);\n};\n\n/** Detect a tar header, including legacy pre-ustar archives, by its checksum. */\nexport function sniffTar(bytes: Uint8Array): boolean {\n\tif (bytes.byteLength < BLOCK_SIZE) return false;\n\tif (isZeroBlock(bytes, 0)) return true;\n\ttry {\n\t\tif (readTarString(bytes, NAME_OFFSET, NAME_LENGTH).length === 0) return false;\n\t\tconst size = readTarSize(bytes, SIZE_OFFSET);\n\t\treturn Number.isSafeInteger(paddedSize(size)) && checksumMatches(bytes, 0);\n\t} catch {\n\t\treturn false;\n\t}\n}\n","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/tar.ts#L568-L604","documentation":"readTar reads the entire archive source into memory before parsing. If readAllBytes throws a non-ArchiveError (stream I/O failure, decode error, etc.), it is wrapped in this generic ArchiveError so callers only need to catch one type. The underlying cause message is preserved when the original error is an Error instance.","triggerScenarios":"Passing a source whose underlying stream/socket/file fails during readAllBytes — closed file descriptor, EACCES on an opened-but-revoked file, network stream reset mid-read, or a source reader that throws a non-Archive error.","commonSituations":"Reading a tar from an HTTP response whose connection dropped, reading from a file deleted or permission-revoked between open and read, custom source implementations whose read() rejects, disk I/O errors.","solutions":["Inspect the wrapped message (or the original console/log) for the real I/O cause and fix that first","Verify the file/source is readable and unchanged before calling readTar","Re-download or re-open the archive; retry only if the cause was transient (network)","If you supply a custom source, ensure its read/byte-returning contract never rejects except on real failures"],"exampleFix":"// before: source may be a dying stream\nawait readTar({ stream: resp.body, ... });\n// after: buffer to a stable file first, then read\nawait Bun.write(tmp, resp);\nawait readTar({ size: tmp.size, bytes: await Bun.file(tmp).bytes(), ... });","handlingStrategy":"try-catch","validationCode":"const stat = await fs.stat(path);\nif (!stat.isFile()) throw new Error(\"not a readable regular file\");","typeGuard":"function isArchiveError(err: unknown): err is ArchiveError {\n  return err instanceof ArchiveError;\n}","tryCatchPattern":"try {\n  return await readTar(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message === \"Failed to read tar archive\") {\n    // underlying I/O failed: check disk, permissions, or stream state\n  }\n  throw err;\n}","preventionTips":["Copy network streams to a local file before parsing","Keep a stable reference to the file — avoid reading files being rotated/deleted","Wrap custom source read() implementations so they throw ArchiveError with the real cause"],"tags":["tar","io","stream","error-wrapping"],"backgroundTag":"archive-read-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}