{"record":{"id":"3c648ba2727a3692","repo":"mozilla/pdf.js","slug":"coverage-search-failed-result-error-message","errorCode":null,"errorMessage":"coverage_search failed: ${result.error.message}","messagePattern":"coverage_search failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gulpfile.mjs","lineNumber":930,"sourceCode":"// For a --code=<file>::<line|function> argument, runs coverage_search to find\n// the ref tests that exercise that location and returns their IDs (an empty\n// array when none match locally). Returns null when --code wasn't given; throws\n// when the search itself fails.\nfunction resolveCodeTestIds() {\n  const codeArg = getArgValue(\"--code\");\n  if (!codeArg) {\n    return null;\n  }\n  // Inherit stderr so the index download progress is visible; stdout is\n  // captured because it carries the matching test IDs.\n  const result = spawnSync(\"node\", getCoverageSearchArgs(codeArg), {\n    encoding: \"utf8\",\n    stdio: [\"ignore\", \"pipe\", \"inherit\"],\n  });\n  if (result.status !== 0) {\n    // status is null when the child couldn't be spawned or was killed by a\n    // signal; surface the real cause instead of a generic message.\n    throw new Error(\n      result.error\n        ? `coverage_search failed: ${result.error.message}`\n        : `coverage_search failed (exit code ${result.status})`\n    );\n  }\n  let testIds = result.stdout.trim().split(\"\\n\").filter(Boolean);\n\n  // The published index is built from master, so some covering tests may not\n  // exist on this branch. Drop them (with a note) rather than letting test.mjs\n  // reject the whole run — and silently exit 0 — on the first unknown ID.\n  const knownIds = readManifestTestIds();\n  if (knownIds) {\n    const missing = testIds.filter(id => !knownIds.has(id));\n    if (missing.length) {\n      console.log(\n        `\\n### Ignoring ${missing.length} covered test(s) not in the manifest:\\n` +\n          missing.map(id => `  ${id}`).join(\"\\n\")\n      );","sourceCodeStart":912,"sourceCodeEnd":948,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/gulpfile.mjs#L912-L948","documentation":"resolveCodeTestIds() spawns `node external/ccov/coverage_search.mjs` via spawnSync to find tests covering the changed code. When `result.status` is non-zero AND `result.error` is set, Node itself could not launch the child process — the binary/script was missing, permissions denied, or spawn hit an OS error. The thrown message embeds `result.error.message` (e.g. ENOENT) to surface the real cause rather than a generic 'failed'. This is the spawn-failure branch of the coverage gating.","triggerScenarios":"`node` is not on PATH in the build environment; `external/ccov/coverage_search.mjs` does not exist ( submodule not initialized, file deleted ); execute permission / shebang issues; EACCES on the working directory; spawning after the process table is exhausted.","commonSituations":"Fresh clone where the ccov data wasn't fetched; a container image missing node; a CI matrix that overrides PATH; running the coverage task on a branch that pre-dates coverage_search.mjs.","solutions":["Verify `node` is installed and on PATH: `node --version`.","Ensure `external/ccov/coverage_search.mjs` exists; fetch/redownload the ccov tooling if absent.","Read `result.error.message` (printed in the thrown text) — ENOENT points to a missing binary/script, EACCES to permissions.","If you don't need coverage selection, drop the `--code=<path>` argument so resolveCodeTestIds returns null and never spawns."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { existsSync } from 'fs';\nfunction canSpawnCoverageSearch() {\n  return existsSync('external/ccov/coverage_search.mjs') && !!process.execPath;\n}","typeGuard":null,"tryCatchPattern":"try {\n  testIds = resolveCodeTestIds();\n} catch (e) {\n  if (/coverage_search failed/.test(e.message) && /ENOENT/.test(e.message)) {\n    console.warn('coverage_search tooling missing; running full test set instead.');\n    testIds = null;\n  } else throw e;\n}","preventionTips":["Ensure `node` is on PATH and `external/ccov/coverage_search.mjs` exists before invoking the coverage task.","If you don't need coverage selection, omit `--code=<path>` so the spawn never happens.","Pin the ccov tooling version in CI to avoid drift."],"tags":["build","coverage","child-process","spawn","toolchain"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}