{"record":{"id":"bbe1d7001dcb5bbc","repo":"mozilla/pdf.js","slug":"missing-hash-commit-hash-argument","errorCode":null,"errorMessage":"Missing \"--hash <commit-hash>\" argument.","messagePattern":"Missing \"--hash <commit-hash>\" argument\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gulpfile.mjs","lineNumber":1120,"sourceCode":"  done();\n});\n\ngulp.task(\"default\", function (done) {\n  console.log(\"Available tasks:\");\n  const tasks = Object.keys(gulp.registry().tasks());\n  for (const taskName of tasks.sort()) {\n    if (taskName.endsWith(\"-pre\")) {\n      continue;\n    }\n    console.log(\"  \" + taskName);\n  }\n  done();\n});\n\ngulp.task(\"release-brotli\", async function (done) {\n  const hashIndex = process.argv.indexOf(\"--hash\");\n  if (hashIndex === -1 || hashIndex + 1 >= process.argv.length) {\n    throw new Error('Missing \"--hash <commit-hash>\" argument.');\n  }\n  console.log();\n  console.log(\"### Getting Brotli js file for release\");\n\n  const OUTPUT_DIR = \"./external/brotli/\";\n  const hash = process.argv[hashIndex + 1];\n  const url = `https://raw.githubusercontent.com/google/brotli/${hash}/js/decode.js`;\n  const outputPath = OUTPUT_DIR + \"decode.js\";\n  const res = await fetch(url);\n  const fileStream = fs.createWriteStream(outputPath, { flags: \"w\" });\n  await finished(stream.Readable.fromWeb(res.body).pipe(fileStream));\n  fileStream.end();\n\n  console.log(`Brotli js file saved to: ${outputPath}`);\n\n  done();\n});\n","sourceCodeStart":1102,"sourceCodeEnd":1138,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/gulpfile.mjs#L1102-L1138","documentation":"The `release-brotli` gulp task downloads the Brotli decoder (`decode.js`) pinned to a specific google/brotli commit. It requires `--hash <commit-hash>` on the command line; the code scans process.argv for `--hash` and checks that a value follows it. If the flag is absent or is the last token (no value), the task aborts before touching the network. This prevents downloading an arbitrary/latest commit and forces a deliberate, reproducible pin.","triggerScenarios":"Running `gulp release-brotli` with no `--hash`; passing `--hash` as the final argument with no commit hash after it; a typo'd flag name (e.g. `--commit`).","commonSituations":"Cutting a release and forgetting the hash; copy-pasting an old release command whose hash field was never filled in; CI release job template missing the substitution.","solutions":["Pass a full commit hash: `gulp release-brotli --hash <40-char-sha>` (use the google/brotli commit you want to vendor).","Verify the hash exists in google/brotli before running (avoids a later 404 on the fetch).","Update your release runbook so the `--hash` value is mandatory and templated."],"exampleFix":"# before\ngulp release-brotli\n# after\ngulp release-brotli --hash c85afa57ab24b1f4d1a4c48e63d44a3d49f4caa2","handlingStrategy":"validation","validationCode":"function assertHashArg(argv) {\n  const i = argv.indexOf('--hash');\n  const v = i !== -1 ? argv[i + 1] : undefined;\n  if (!v || !/^[0-9a-f]{7,40}$/i.test(v)) {\n    throw new Error('release-brotli requires --hash <commit-hash> (7-40 hex chars)');\n  }\n  return v;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make --hash mandatory in your release runbook and template the value.","Verify the hash exists in google/brotli before running (avoids a later 404).","Use full 40-char SHAs for reproducibility."],"tags":["release","cli","build","argv","brotli"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}