Summary
mcpb unpack aborts with an error on any .mcpb/ZIP archive that contains explicit directory entries (keys ending in /). Since .mcpb is defined as a ZIP and most ZIP tooling (zip -r, many language libraries) emits directory entries, unpack fails on the majority of real-world bundles not produced by mcpb pack itself.
Mechanism
src/cli/unpack.ts:94-113 — fflate's unzipSync returns directory entries as keys ending in / with zero-length data. The loop does writeFileSync(join(outputDir, "server/"), data) unconditionally; the trailing slash makes the write fail (ENOENT/EISDIR), the throw propagates to the outer catch, and the whole unpack returns false — nothing is extracted. Directory entries are never skipped.
(mcpb pack only emits file entries, so an mcpb→mcpb round-trip hides this.)
Reproduction
mkdir -p server && echo "x" > server/index.js
zip -r demo.zip server # standard zip emits a `server/` directory entry
cp demo.zip demo.mcpb
mcpb unpack demo.mcpb out/
# ERROR: Failed to unpack extension: ENOENT: no such file or directory, open '.../out/server/'
# nothing extracted
Suggested fix
Skip directory entries before writing:
for (const relativePath in decompressed) {
if (relativePath.endsWith("/")) continue; // directory entry
...
}
The parent-directory mkdirSync already creates needed directories, so no functionality is lost.
Environment: current main (70fe3b3).
Summary
mcpb unpackaborts with an error on any.mcpb/ZIP archive that contains explicit directory entries (keys ending in/). Since.mcpbis defined as a ZIP and most ZIP tooling (zip -r, many language libraries) emits directory entries,unpackfails on the majority of real-world bundles not produced bymcpb packitself.Mechanism
src/cli/unpack.ts:94-113— fflate'sunzipSyncreturns directory entries as keys ending in/with zero-length data. The loop doeswriteFileSync(join(outputDir, "server/"), data)unconditionally; the trailing slash makes the write fail (ENOENT/EISDIR), the throw propagates to the outercatch, and the whole unpack returnsfalse— nothing is extracted. Directory entries are never skipped.(
mcpb packonly emits file entries, so an mcpb→mcpb round-trip hides this.)Reproduction
Suggested fix
Skip directory entries before writing:
The parent-directory
mkdirSyncalready creates needed directories, so no functionality is lost.Environment: current
main(70fe3b3).