can1357/oh-my-pi · error · ArchiveError
Archive file '${normalizedPath}' has no readable storage
Error message
Archive file '${normalizedPath}' has no readable storage What it means
ArchiveError thrown by ArchiveReader.readFile() when the entry exists and is a file, but entry.storage is unset — the archive records the member but its content bytes are not available/readable through the reader. The library refuses to proceed instead of silently returning empty data.
Source
Thrown at packages/utils/src/ar/reader.ts:145
async readFile(subPath: string): Promise<ExtractedArchiveFile> {
const normalizedPath = normalizeArchiveLookupPath(subPath);
if (!normalizedPath) {
throw new ArchiveError("Archive file path is required");
}
const resolvedPath = resolveArchiveLinkPath(this.#entries, normalizedPath, this.limits.maxLinkDepth);
if (resolvedPath === "") {
throw new ArchiveError(`Archive path '${normalizedPath}' is a directory`);
}
const entry = this.#entries.get(resolvedPath);
if (!entry) {
throw new ArchiveError(`Archive file '${normalizedPath}' not found`);
}
if (entry.isDirectory) {
throw new ArchiveError(`Archive path '${normalizedPath}' is a directory`);
}
if (!entry.storage) {
throw new ArchiveError(`Archive file '${normalizedPath}' has no readable storage`);
}
assertArchiveMemberSize(entry.size, normalizedPath, this.limits);
if (entry.storage.type === "link") {
throwUnreadableArchiveLink(entry.storage.targetPath, normalizedPath);
}
const bytes = await entry.storage.source.read(entry.size, normalizedPath);
return {
path: normalizedPath,
isDirectory: false,
size: entry.size,
mtimeMs: entry.mtimeMs,
mode: entry.mode,
bytes,
};
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Re-verify the archive file is complete and uncorrupted (compare checksums)
- Inspect the entry via the reader's listing API to confirm storage type before reading
- If the archive is a link-type or unsupported storage, handle those members separately
- Regenerate or re-download the archive
Example fix
// before
const data = await reader.readFile(name);
// after
try {
const data = await reader.readFile(name);
} catch (err) {
if (err instanceof ArchiveError && /no readable storage/.test(err.message)) {
// treat member as unreadable metadata-only entry
}
} Defensive patterns
Strategy: try-catch
Validate before calling
const entry = reader.getEntry?.(name);
if (entry && !entry.isDirectory && !entry.storage) {
throw new Error(`member '${name}' has no readable storage`);
} Type guard
function hasStorage(e: { storage?: unknown } | undefined): e is { storage: object } {
return e !== undefined && e.storage != null;
} Try / catch
try {
const data = await reader.readFile(name);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('no readable storage')) {
// treat as metadata-only member; fall back to re-fetching the archive
} else throw err;
} Prevention
- Validate archive integrity (checksum) before parsing
- Inspect entry storage types via listing before reading
- Re-fetch archives that parse with missing storage
When it happens
Trigger: Calling reader.readFile(path) on a member whose parsed entry has no storage record (e.g. archive format stores metadata-only entries or the storage was not attached during parsing).
Common situations: Reading members from unusual or partially supported archive variants where the parser recognized the entry name but not its data section; corrupted or non-standard archives.
Related errors
- Bzip2 block exhausted its Huffman selectors
- Bzip2 block exceeds its declared block-size level
- Corrupt compress (.Z) dictionary code ${code}
- Corrupt compress (.Z) dictionary chain
- Invalid CAB archive: misaligned LZX byte stream
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/42e49cb55e9bafc3.
Report an issue: GitHub.