can1357/oh-my-pi · error · ArchiveError
Invalid archive link
Error message
Invalid archive link
What it means
Wraps a non-ArchiveError failure from resolveArchiveLinkPath into a generic ArchiveError("Invalid archive link") during pending-link resolution. It means link-target resolution failed in an unexpected way while settling a tar symlink/hard-link entry.
Source
Thrown at packages/utils/src/ar/tar.ts:362
const findUnresolvedBlocker = (targetPath: string): ArchiveIndexEntry | null => {
for (let end = targetPath.length; end > 0; end = targetPath.lastIndexOf("/", end - 1)) {
const prefixEntry = entries.get(targetPath.slice(0, end));
if (prefixEntry && unresolved.has(prefixEntry)) return prefixEntry;
}
return null;
};
const queue = [...unresolved];
while (queue.length > 0) {
const entry = queue.pop()!;
if (!unresolved.has(entry)) continue;
const pending = pendingLinks.get(entry)!;
let blocker = findUnresolvedBlocker(pending.targetPath);
let targetPath = pending.targetPath;
if (blocker === null) {
try {
targetPath = resolveArchiveLinkPath(entries, targetPath, limits.maxLinkDepth);
} catch (error) {
if (!(error instanceof ArchiveError)) throw new ArchiveError("Invalid archive link");
}
if (targetPath !== pending.targetPath) blocker = findUnresolvedBlocker(targetPath);
}
if (blocker !== null && blocker !== entry) {
const waiting = dependents.get(blocker);
if (waiting) waiting.push(entry);
else dependents.set(blocker, [entry]);
continue;
}
unresolved.delete(entry);
const settled = dependents.get(entry);
if (settled) {
dependents.delete(entry);
queue.push(...settled);
}
if (blocker === entry) {
if (pending.kind === "hard link") {
throw new ArchiveError(View on GitHub (pinned to 9690622007)
Solutions
- Inspect the original error by catching ArchiveError and checking message context; enable debug logging to see the failing link.
- Examine the archive's link structure (`tar tvf`) for unusually deep symlink chains and re-pack without them.
- Report a bug with the offending archive if a normal archive triggers it — non-ArchiveError escapes here suggest a library defect.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await readTar(bytes, opts);
} catch (e) {
if (e instanceof ArchiveError && e.message === "Invalid archive link") {
logger.error("tar link resolution failed unexpectedly", { error: e });
throw new Error("Archive link graph could not be resolved");
}
throw e;
} Prevention
- Avoid archives with deep or chained symlink structures.
- Re-pack with `tar -h` (dereference) when link graphs are complex.
- Report reproducible cases to the library maintainers — this wraps non-ArchiveError bugs.
When it happens
Trigger: During resolvePendingLinks, resolveArchiveLinkPath(entries, targetPath, maxLinkDepth) throws something that is not an ArchiveError (e.g. a RangeError from runaway recursion or an internal bug), so the catch block re-wraps it.
Common situations: Pathological archives with deeply nested or self-referential symlink chains that trip the depth limit via an unexpected error type; library-internal edge cases.
Related errors
- Archive contains cyclic or unsupported links
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- Unsafe embedded addon archive entry: ${filename}
- Unsupported embedded addon archive entry type ${typeflag}: $
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/fdf52d44edd85a6a.
Report an issue: GitHub.