{"record":{"id":"a52f73ee26389984","repo":"Automattic/harper","slug":"weirpack-is-missing-manifest-json","errorCode":null,"errorMessage":"Weirpack is missing manifest.json","messagePattern":"Weirpack is missing manifest\\.json","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/harper.js/src/weirpack.ts","lineNumber":15,"sourceCode":"import { strFromU8, strToU8, unzipSync, zipSync } from 'fflate';\n\nexport type WeirpackArchive = {\n\tmanifest: Record<string, unknown>;\n\tfiles: Map<string, string>;\n};\n\nconst manifestFilename = 'manifest.json';\n\n/** Convert a Weirpack file system into a real Weirpack binary by compressing and serializing them into a byte array.\n *\n * For clarity on what a Weirpack is, read [the Weir documentation.](https://writewithharper.com/docs/weir#Weirpacks) */\nexport function packWeirpackFiles(files: Map<string, string>): Uint8Array {\n\tif (!files.has(manifestFilename)) {\n\t\tthrow new Error('Weirpack is missing manifest.json');\n\t}\n\n\tconst entries: Record<string, Uint8Array> = {};\n\tfor (const [name, content] of files.entries()) {\n\t\tentries[name] = strToU8(content);\n\t}\n\n\treturn zipSync(entries, { level: 6 });\n}\n\n/** Decompress and deserialize a Weirpack from a byte array. */\nexport function unpackWeirpackBytes(bytes: Uint8Array): WeirpackArchive {\n\tconst archive = unzipSync(bytes);\n\tconst manifestBytes = archive[manifestFilename];\n\tif (!manifestBytes) {\n\t\tthrow new Error('Weirpack is missing manifest.json');\n\t}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/Automattic/harper/blob/5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83/packages/harper.js/src/weirpack.ts#L1-L33","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the manifest under the exact key 'manifest.json': files.set('manifest.json', JSON.stringify(manifest))","Normalize keys (strip leading './' or '/') when building the map from paths","Check your glob/gather step actually includes the manifest file","Verify the manifest JSON parses and has required Weirpack fields before packing"],"exampleFix":"// before\nconst files = new Map([['./manifest.json', manifestJson]]);\n// after\nconst files = new Map([['manifest.json', manifestJson]]);","handlingStrategy":"validation","validationCode":"const manifestFilename = 'manifest.json';\nif (!files.has(manifestFilename)) {\n  throw new Error('Add manifest.json at the archive root before packing');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const bytes = packWeirpackFiles(files);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Weirpack is missing manifest.json') {\n    files.set('manifest.json', JSON.stringify(manifest));\n    return packWeirpackFiles(files);\n  }\n  throw e;\n}","preventionTips":["Always set the manifest under the exact key 'manifest.json'","Normalize gathered file keys (strip './' prefixes) before packing","Assert manifest.json presence in your build script"],"tags":["weirpack","missing-file","manifest"],"backgroundTag":"file-not-found","analyzedSha":"5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83","analyzedAt":"2026-09-06T11:34:38.610Z","contentChangedAt":"2026-09-06T11:34:38.610Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}