{"record":{"id":"ccc687f678fd38a6","repo":"can1357/oh-my-pi","slug":"archive-hard-link-formatarchivepathforerror-ent-ccc687","errorCode":null,"errorMessage":"Archive hard link '${formatArchivePathForError(entry.path)}' targets ${reason} '${formatArchivePathForError(pending.targetPath)}'","messagePattern":"Archive hard link '(.+?)' targets (.+?) '(.+?)'","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/tar.ts","lineNumber":400,"sourceCode":"\t\t\t\t);\n\t\t\t}\n\t\t\tentry.storage = { type: \"link\", targetPath: pending.targetPath, resolveTarget: false };\n\t\t\tcontinue;\n\t\t}\n\t\tconst target = entries.get(targetPath);\n\t\tif (target?.storage && !target.isDirectory && !unresolved.has(target)) {\n\t\t\tentry.size = target.size;\n\t\t\tentry.storage = target.storage;\n\t\t\tcontinue;\n\t\t}\n\t\tconst targetIsDirectory = targetPath === \"\" || target?.isDirectory === true || directoryPrefixes.has(targetPath);\n\t\tif (!targetIsDirectory) {\n\t\t\tif (pending.kind === \"symlink\") {\n\t\t\t\tentry.storage = { type: \"link\", targetPath: pending.targetPath, resolveTarget: false };\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst reason = target ? \"unreadable member\" : \"missing member\";\n\t\t\tthrow new ArchiveError(\n\t\t\t\t`Archive hard link '${formatArchivePathForError(entry.path)}' targets ${reason} '${formatArchivePathForError(pending.targetPath)}'`,\n\t\t\t);\n\t\t}\n\t\tif (pending.kind === \"hard link\") {\n\t\t\tthrow new ArchiveError(\n\t\t\t\t`Archive hard link '${formatArchivePathForError(entry.path)}' targets directory '${formatArchivePathForError(pending.targetPath)}'`,\n\t\t\t);\n\t\t}\n\t\tentry.isDirectory = true;\n\t\tentry.storage = { type: \"link\", targetPath: pending.targetPath, resolveTarget: false };\n\t}\n\tif (unresolved.size > 0) throw new ArchiveError(\"Archive contains cyclic or unsupported links\");\n}\n\n/** Index an already-decompressed tar buffer with bounded GNU, ustar, and PAX handling. */\nexport function readTarEntriesFromBuffer(buffer: Uint8Array, options: FormatReadOptions): ArchiveIndexEntry[] {\n\tconst { limits } = options;\n\tassertInMemorySize(buffer.byteLength, limits);","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/tar.ts#L382-L418","documentation":"Thrown when a tar hard link's target resolves to a path that is not a directory and has no readable file member behind it — either the target member exists but has no readable storage ('unreadable member', e.g. a symlink kept as a raw link) or no member exists at all ('missing member'). Hard links require a concrete file target.","triggerScenarios":"readTar on an archive with a typeflag-'1' entry whose linkname points at a path absent from the index, or at a member whose storage cannot be shared (e.g. a dangling symlink target).","commonSituations":"Archives extracted/re-packed lossily so the hard-link target file was dropped; tools emitting hard links before their target member; hand-crafted archives.","solutions":["Check `tar tvf` for the target path named in the message and confirm the file member is present.","Re-create the archive ensuring hard-link targets are archived as regular files (GNU tar archives targets in full when needed).","If you control archive generation, emit hard links after their target member, or replace hard links with regular file copies."],"exampleFix":"// before (creating archive): hard link with target omitted\ntar -cf out.tar link-only-dir/\n// after: include the target file or dereference links\ntar -cf out.tar -h dir/","handlingStrategy":"validation","validationCode":"// Verify with system tar before indexing that all hardlink targets exist\n// $ tar -tvf archive.tar | review typeflag-1 entries and their targets","typeGuard":null,"tryCatchPattern":"try {\n  await readTar(bytes, opts);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.includes(\"targets unreadable member\") ||\n      e instanceof ArchiveError && e.message.includes(\"targets missing member\")) {\n    throw new Error(\"Archive hard link points at a missing/unreadable member; re-create archive\");\n  }\n  throw e;\n}","preventionTips":["Create archives so hard-link targets are included as regular file members.","Emit hard links after their target member in the archive stream.","Use `tar -h` to dereference links when portability matters more than space."],"tags":["archive","tar","hardlink","missing-target"],"backgroundTag":"hardlink-target-missing","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}