{"record":{"id":"0de45ddf4fa11b36","repo":"ruvnet/ruflo","slug":"build-input-bytes-must-be-a-non-negative-safe-inte","errorCode":null,"errorMessage":"build input bytes must be a non-negative safe integer","messagePattern":"build input bytes must be a non-negative safe integer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/harness/build-evidence.ts","lineNumber":120,"sourceCode":"export function createBuildEvidence(\n  sourceState: ExactSourceState,\n  buildInputs: readonly DeclaredBuildInput[],\n  toolchains: readonly DeclaredToolchain[],\n): BuildEvidence {\n  const inputs = buildInputs.map((input) => ({\n    name: requireText(input.name, 'build input name'),\n    path: normalizePath(input.path),\n    digest: requireDigest(input.digest, 'build input digest'),\n    bytes: input.bytes,\n  })).sort((left, right) => compare(left.path, right.path) || compare(left.name, right.name));\n  const tools = toolchains.map((toolchain) => ({\n    name: requireText(toolchain.name, 'toolchain name'),\n    version: requireText(toolchain.version, 'toolchain version'),\n    digest: requireDigest(toolchain.digest, 'toolchain digest'),\n  })).sort((left, right) => compare(left.name, right.name) || compare(left.version, right.version));\n\n  if (inputs.some(({ bytes }) => !Number.isSafeInteger(bytes) || bytes < 0)) {\n    throw new Error('build input bytes must be a non-negative safe integer');\n  }\n  const inputKeys = inputs.map(({ name, path }) => `${name}\\0${path}`);\n  if (new Set(inputKeys).size !== inputKeys.length) throw new Error('duplicate declared build input');\n  const foldedPaths = inputs.map(({ path }) => portableCaseFold(path));\n  if (new Set(foldedPaths).size !== foldedPaths.length) {\n    throw new Error('case-fold collision in declared build inputs');\n  }\n  const toolKeys = tools.map(({ name, version }) => `${name}\\0${version}`);\n  if (new Set(toolKeys).size !== toolKeys.length) throw new Error('duplicate declared toolchain');\n\n  const body = {\n    contractVersion: 1 as const,\n    assurance: 'declared-unsigned' as const,\n    sourceStateId: requireDigest(sourceState.sourceStateId, 'source state id'),\n    buildInputs: inputs,\n    toolchains: tools,\n  };\n  return { ...body, evidenceDigest: sha256(canonicalJson(body)) };","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/harness/build-evidence.ts#L102-L138","documentation":"Each DeclaredBuildInput.bytes value must satisfy Number.isSafeInteger(bytes) && bytes >= 0. Negative values, fractional values, NaN, Infinity, and integers beyond Number.MAX_SAFE_INTEGER (2^53-1) all throw when createBuildEvidence validates the folded input list, because the evidence contract must hash to identical bytes on every platform.","triggerScenarios":"bytes set to -1; bytes computed as a float (averages, unit conversions, sizes divided by 1024.0); NaN propagated from parsing; a byte count larger than 2^53-1.","commonSituations":"Sizes measured by external tools and parsed from strings; BigInt file sizes converted with Number() losing precision; uninitialized size fields defaulting to NaN in generated declarations.","solutions":["Audit every buildInputs[].bytes value — all must be whole numbers ≥ 0 and ≤ 2^53-1","Fix the measurement source: use integer byte counts from fs stat (stat.size), not derived floats","If a genuine input exceeds 2^53-1 bytes, split it or declare a manifest of it — the contract cannot represent that size"],"exampleFix":"// before\nbytes: stats.size / 1024, // fractional KB value\nbytes: -1,\n\n// after\nbytes: stats.size, // integer byte length from fs.Stats","handlingStrategy":"validation","validationCode":"function isValidByteCount(bytes: unknown): bytes is number {\n  return typeof bytes === 'number' && Number.isSafeInteger(bytes) && bytes >= 0;\n}","typeGuard":"function isValidByteCount(bytes: unknown): bytes is number {\n  return typeof bytes === 'number' && Number.isSafeInteger(bytes) && bytes >= 0;\n}","tryCatchPattern":null,"preventionTips":["Take sizes directly from fs.Stats.size (already a safe integer)","Never derive bytes through division or averaging without Math.round and bounds checks","Validate deserialized JSON size fields before they reach evidence creation"],"tags":["build-evidence","numeric-validation","harness"],"backgroundTag":"invalid-numeric-value","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}