Skip to content

mcpb unpack fails on archives containing directory entries (unusable on standard ZIP/.mcpb files) #261

@aosmcleod

Description

@aosmcleod

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions