can1357/oh-my-pi · error · ArchiveError
Archive path '${normalizedPath}' not found
Error message
Archive path '${normalizedPath}' not found What it means
`listDirectory` resolved the requested path (following symlinks up to maxLinkDepth) but no entry exists under the resolved path in the archive's entry map, so it throws ArchiveError(`Archive path '${normalizedPath}' not found`). The message reports the originally requested path, not the resolved one (packages/utils/src/ar/reader.ts:85).
Source
Thrown at packages/utils/src/ar/reader.ts:85
mtimeMs: entry.mtimeMs,
mode: entry.mode,
};
}
/** List one directory's children, sorted case-insensitively by name. */
listDirectory(subPath?: string): ArchiveDirectoryEntry[] {
const normalizedPath = normalizeArchiveLookupPath(subPath);
if (normalizedPath === undefined) {
throw new ArchiveError("Archive path cannot contain '..'");
}
const resolvedPath = normalizedPath
? resolveArchiveLinkPath(this.#entries, normalizedPath, this.limits.maxLinkDepth)
: "";
if (normalizedPath && resolvedPath !== "") {
const entry = this.#entries.get(resolvedPath);
if (!entry) {
throw new ArchiveError(`Archive path '${normalizedPath}' not found`);
}
if (!entry.isDirectory) {
throw new ArchiveError(`Archive path '${normalizedPath}' is not a directory`);
}
}
const sourcePrefix = resolvedPath ? `${resolvedPath}/` : "";
const children = new Map<string, ArchiveDirectoryEntry>();
for (const entry of this.#entries.values()) {
if (resolvedPath) {
if (!entry.path.startsWith(sourcePrefix) || entry.path === resolvedPath) continue;
}
const relativePath = resolvedPath ? entry.path.slice(sourcePrefix.length) : entry.path;
const nextSegment = relativePath.split("/")[0];
if (!nextSegment) continue;
View on GitHub (pinned to 9690622007)
Solutions
- List available entries first (`reader.allEntries()` or listDirectory(undefined) for the root) and confirm the exact path/case before calling again.
- Normalize the path (strip leading '/', trailing '/') — directories inside archives are matched as stored, e.g. 'sub/dir' with forward slashes.
- If the path comes from a symlink, verify the link target exists in the archive; re-create the archive if the target was never added.
- Catch ArchiveError with 'not found' and fall back to a root listing or a closest-match search for the user.
Example fix
// before: assuming the dir exists
reader.listDirectory('src/utils');
// after: verify against actual entries first
const entries = reader.allEntries();
const wanted = 'src/utils';
if (!entries.some(e => e.isDirectory && (e.path === wanted || e.path === wanted + '/'))) {
throw new Error(`No such directory in archive: ${wanted}`);
}
reader.listDirectory(wanted); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the directory exists (exact path/case) before listing
const entries = reader.allEntries();
const wanted = 'src/utils';
if (!entries.some(e => e.isDirectory && (e.path === wanted || e.path === wanted + '/'))) {
throw new Error(`Directory not in archive: ${wanted}`);
}
reader.listDirectory(wanted); Type guard
function hasDirectory(entries: { path: string; isDirectory: boolean }[], dir: string): boolean {
return entries.some(e => e.isDirectory && (e.path === dir || e.path === dir + '/'));
} Try / catch
try {
return reader.listDirectory(dirPath);
} catch (err) {
if (err instanceof ArchiveError && err.message.endsWith("not found")) {
logger.warn('Archive directory missing; falling back to root', { dirPath });
return reader.listDirectory(); // root listing
}
throw err;
} Prevention
- Always derive paths from allEntries() output rather than hard-coding them.
- Remember lookups are case-sensitive; match stored casing exactly.
- Normalize to forward slashes with no leading/trailing separators.
- After repacking archives, re-validate any consumers that reference fixed paths.
When it happens
Trigger: Calling `reader.listDirectory('missing/dir')` where no entry with that path exists; a symlinked directory whose target is absent (resolveArchiveLinkPath returns non-empty but lookup misses); typo'd or case-mismatched path (lookups are case-sensitive here).
Common situations: Hard-coded paths that don't match the actual archive layout; archives where folders only appear as prefixes of file entries and the directory entry itself doesn't exist; path casing differs (README.DOC vs readme.doc); typos in tooling or scripts.
Related errors
- Archive file '${normalizedPath}' not found
- Path not found: ${partition.missing.join(", ")}
- Archive path '${normalizedPath}' is not a directory
- cannot access {}: Not a directory
- invalid template, {}; with --tmpdir, it may not be absolute
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6002c77fca716923.
Report an issue: GitHub.