{"record":{"id":"42e49cb55e9bafc3","repo":"can1357/oh-my-pi","slug":"archive-file-normalizedpath-has-no-readable-s","errorCode":null,"errorMessage":"Archive file '${normalizedPath}' has no readable storage","messagePattern":"Archive file '(.+?)' has no readable storage","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/reader.ts","lineNumber":145,"sourceCode":"\tasync readFile(subPath: string): Promise<ExtractedArchiveFile> {\n\t\tconst normalizedPath = normalizeArchiveLookupPath(subPath);\n\t\tif (!normalizedPath) {\n\t\t\tthrow new ArchiveError(\"Archive file path is required\");\n\t\t}\n\n\t\tconst resolvedPath = resolveArchiveLinkPath(this.#entries, normalizedPath, this.limits.maxLinkDepth);\n\t\tif (resolvedPath === \"\") {\n\t\t\tthrow new ArchiveError(`Archive path '${normalizedPath}' is a directory`);\n\t\t}\n\t\tconst entry = this.#entries.get(resolvedPath);\n\t\tif (!entry) {\n\t\t\tthrow new ArchiveError(`Archive file '${normalizedPath}' not found`);\n\t\t}\n\t\tif (entry.isDirectory) {\n\t\t\tthrow new ArchiveError(`Archive path '${normalizedPath}' is a directory`);\n\t\t}\n\t\tif (!entry.storage) {\n\t\t\tthrow new ArchiveError(`Archive file '${normalizedPath}' has no readable storage`);\n\t\t}\n\t\tassertArchiveMemberSize(entry.size, normalizedPath, this.limits);\n\n\t\tif (entry.storage.type === \"link\") {\n\t\t\tthrowUnreadableArchiveLink(entry.storage.targetPath, normalizedPath);\n\t\t}\n\t\tconst bytes = await entry.storage.source.read(entry.size, normalizedPath);\n\t\treturn {\n\t\t\tpath: normalizedPath,\n\t\t\tisDirectory: false,\n\t\t\tsize: entry.size,\n\t\t\tmtimeMs: entry.mtimeMs,\n\t\t\tmode: entry.mode,\n\t\t\tbytes,\n\t\t};\n\t}\n}\n","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/reader.ts#L127-L163","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst data = await reader.readFile(name);\n// after\ntry {\n  const data = await reader.readFile(name);\n} catch (err) {\n  if (err instanceof ArchiveError && /no readable storage/.test(err.message)) {\n    // treat member as unreadable metadata-only entry\n  }\n}","handlingStrategy":"try-catch","validationCode":"const entry = reader.getEntry?.(name);\nif (entry && !entry.isDirectory && !entry.storage) {\n  throw new Error(`member '${name}' has no readable storage`);\n}","typeGuard":"function hasStorage(e: { storage?: unknown } | undefined): e is { storage: object } {\n  return e !== undefined && e.storage != null;\n}","tryCatchPattern":"try {\n  const data = await reader.readFile(name);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('no readable storage')) {\n    // treat as metadata-only member; fall back to re-fetching the archive\n  } else throw err;\n}","preventionTips":["Validate archive integrity (checksum) before parsing","Inspect entry storage types via listing before reading","Re-fetch archives that parse with missing storage"],"tags":["archive","ar","corrupt-data"],"backgroundTag":"archive-member-unreadable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}