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

  1. List available entries first (`reader.allEntries()` or listDirectory(undefined) for the root) and confirm the exact path/case before calling again.
  2. Normalize the path (strip leading '/', trailing '/') — directories inside archives are matched as stored, e.g. 'sub/dir' with forward slashes.
  3. 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.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6002c77fca716923. Report an issue: GitHub.