Automattic/harper · error · Error

Weirpack is missing manifest.json

Error message

Weirpack is missing manifest.json

What it means

packWeirpackFiles builds a Weirpack binary from a Map of filename→content and requires a manifest entry named manifest.json. Without it the archive has no manifest metadata, so packing is refused with 'Weirpack is missing manifest.json'.

Source

Thrown at packages/harper.js/src/weirpack.ts:15

import { strFromU8, strToU8, unzipSync, zipSync } from 'fflate';

export type WeirpackArchive = {
	manifest: Record<string, unknown>;
	files: Map<string, string>;
};

const manifestFilename = 'manifest.json';

/** Convert a Weirpack file system into a real Weirpack binary by compressing and serializing them into a byte array.
 *
 * For clarity on what a Weirpack is, read [the Weir documentation.](https://writewithharper.com/docs/weir#Weirpacks) */
export function packWeirpackFiles(files: Map<string, string>): Uint8Array {
	if (!files.has(manifestFilename)) {
		throw new Error('Weirpack is missing manifest.json');
	}

	const entries: Record<string, Uint8Array> = {};
	for (const [name, content] of files.entries()) {
		entries[name] = strToU8(content);
	}

	return zipSync(entries, { level: 6 });
}

/** Decompress and deserialize a Weirpack from a byte array. */
export function unpackWeirpackBytes(bytes: Uint8Array): WeirpackArchive {
	const archive = unzipSync(bytes);
	const manifestBytes = archive[manifestFilename];
	if (!manifestBytes) {
		throw new Error('Weirpack is missing manifest.json');
	}

View on GitHub (pinned to 5fe7d5ab76)

Solutions

  1. Add the manifest under the exact key 'manifest.json': files.set('manifest.json', JSON.stringify(manifest))
  2. Normalize keys (strip leading './' or '/') when building the map from paths
  3. Check your glob/gather step actually includes the manifest file
  4. Verify the manifest JSON parses and has required Weirpack fields before packing

Example fix

// before
const files = new Map([['./manifest.json', manifestJson]]);
// after
const files = new Map([['manifest.json', manifestJson]]);
Defensive patterns

Strategy: validation

Validate before calling

const manifestFilename = 'manifest.json';
if (!files.has(manifestFilename)) {
  throw new Error('Add manifest.json at the archive root before packing');
}

Try / catch

try {
  const bytes = packWeirpackFiles(files);
} catch (e) {
  if (e instanceof Error && e.message === 'Weirpack is missing manifest.json') {
    files.set('manifest.json', JSON.stringify(manifest));
    return packWeirpackFiles(files);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling packWeirpackFiles (or the helpers built on it: packed, bytes, buildWeirpackBytes) with a Map that lacks the exact key 'manifest.json' — e.g. key 'manifest.MD', './manifest.json', or building the map conditionally.

Common situations: Path-prefix bugs when assembling the file map (join() prepending './'); loading files from disk where manifest.json wasn't included in the glob; renaming the manifest for organization.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.


AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06). Data as JSON: /api/errors/a52f73ee26389984. Report an issue: GitHub.