{"record":{"id":"b3b9dc9a4e30c591","repo":"santifer/career-ops","slug":"the-release-pointer-does-not-carry-a-sha256-digest","errorCode":null,"errorMessage":"the release pointer does not carry a sha256 digest: ${url}","messagePattern":"the release pointer does not carry a sha256 digest: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/h1b-sponsor/install-h1b-index.mjs","lineNumber":126,"sourceCode":"  });\n  if (out.status) throw new Error(`could not read the release pointer (HTTP ${out.status}): ${url}`);\n  if (out.oversized) throw new Error(`the release pointer is implausibly large: ${url}`);\n\n  let doc;\n  try {\n    doc = JSON.parse(String(out.text || ''));\n  } catch {\n    throw new Error(`the release pointer is not JSON: ${url}`);\n  }\n  if (!doc || typeof doc !== 'object') throw new Error(`the release pointer is not an object: ${url}`);\n\n  const filename = String(doc.filename || '');\n  if (!FILENAME_RE.test(filename)) {\n    throw new Error(`the release pointer names an unusable index filename (${JSON.stringify(doc.filename)}): ${url}`);\n  }\n  const sha256 = String(doc.sha256 || '').trim().toLowerCase();\n  if (!SHA256_RE.test(sha256)) {\n    throw new Error(`the release pointer does not carry a sha256 digest: ${url}`);\n  }\n  // Recorded, never acted on, so a missing or odd value costs a label rather\n  // than the install. Bounded because it lands in a file on disk.\n  const version = doc.version === undefined || doc.version === null\n    ? null\n    : String(doc.version).slice(0, 64);\n  return { filename, sha256, version };\n}\n\n/**\n * Stream the asset to `tmpFile`, hashing as it goes, and return the digest.\n *\n * Streamed rather than buffered: the body is millions of times the size of\n * anything else this plugin reads, and readBoundedText's 1 MiB ceiling exists\n * precisely because nothing on the API path should ever be this big. Hashing\n * during the write means the file is never read a second time to verify it.\n */\nasync function downloadAsset(fetchImpl, url, tmpFile) {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/santifer/career-ops/blob/1696bec4d021768e7359f9aad6b329cba883da20/plugins/h1b-sponsor/install-h1b-index.mjs#L108-L144","documentation":"The pointer object's filename is valid, but its sha256 field is missing or fails SHA256_RE (a 64-hex-character digest). The plugin verifies the downloaded index against this digest, so a pointer without a usable sha256 cannot be trusted and the install aborts. Note doc.version is deliberately optional — only the digest is mandatory.","triggerScenarios":"fetchPointer(url) reads a JSON object with a valid filename but doc.sha256 absent, empty, uppercase-only handling fails, truncated, or otherwise not matching SHA256_RE after trim/lowercase.","commonSituations":"The release pipeline published the pointer before computing the digest; a hand-edited pointer dropped the field; a different plugin version's pointer schema omits sha256; the digest was pasted with formatting (though trim/lowercase already handles whitespace and case).","solutions":["curl the pointer URL and confirm it carries a full 64-character hex sha256 field.","Regenerate the pointer with the correct digest of the published index file (sha256sum).","Check for plugin/endpoint version mismatch — older pointer schemas may lack the field; align versions.","If you do not control the endpoint, wait for the release to be republished and retry."],"exampleFix":"// before\n{\"filename\":\"h1b-index-2026-08-30.json\"}\n// after\n{\"filename\":\"h1b-index-2026-08-30.json\",\"sha256\":\"9f2a…(64 hex chars)\"}","handlingStrategy":"validation","validationCode":"const doc = JSON.parse(await (await fetch(pointerUrl)).text());\nconst SHA256_RE = /^[0-9a-f]{64}$/;\nconst sha = String(doc?.sha256 ?? '').trim().toLowerCase();\nif (!SHA256_RE.test(sha)) throw new Error('pointer sha256 missing/malformed; install will be rejected');","typeGuard":"function hasSha256(doc) {\n  return !!doc && typeof doc.sha256 === 'string' && /^[0-9a-f]{64}$/.test(doc.sha256.trim().toLowerCase());\n}","tryCatchPattern":"try {\n  await installH1BIndex();\n} catch (e) {\n  if (String(e.message).includes('sha256 digest')) {\n    console.error('Pointer lacks a valid sha256; republish the pointer with the digest of the index file.');\n  } else throw e;\n}","preventionTips":["Generate pointers via the release script so sha256 is always computed and included.","Never hand-edit pointer files; regenerate instead.","CI-check the published pointer for a 64-hex sha256 before announcing a release.","Verify the digest matches the uploaded asset (sha256sum) as part of the release checklist."],"tags":["validation","checksum","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"1696bec4d021768e7359f9aad6b329cba883da20","analyzedAt":"2026-09-01T19:19:23.111Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}