{"record":{"id":"67eeb45434d2bc00","repo":"ruvnet/ruflo","slug":"run-execution-session-and-workload-identity-are","errorCode":null,"errorMessage":"run execution, session, and workload identity are required","messagePattern":"run execution, session, and workload identity are required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/harness/in-memory-run-receipt-reference.ts","lineNumber":23,"sourceCode":"const DIGEST = /^sha256:[0-9a-f]{64}$/;\n\nfunction sha256(value: string): string {\n  return `sha256:${createHash('sha256').update(value).digest('hex')}`;\n}\n\nfunction copy<T>(value: T): T {\n  return structuredClone(value);\n}\n\nfunction timestamp(value: string, label: string): number {\n  const parsed = Date.parse(value);\n  if (!Number.isFinite(parsed)) throw new Error(`${label} must be an ISO timestamp`);\n  return parsed;\n}\n\nfunction validateRun(run: RunEvidence): void {\n  if (!run.executionId.trim() || !run.sessionId.trim() || !run.workloadId.trim()) {\n    throw new Error('run execution, session, and workload identity are required');\n  }\n  if (!DIGEST.test(run.sourceState.sourceStateId)) throw new Error('run sourceStateId is invalid');\n  if (!DIGEST.test(run.commandDigest) || !DIGEST.test(run.evidenceDigest)) {\n    throw new Error('run command and evidence digests must be canonical sha256 values');\n  }\n  if (!Number.isSafeInteger(run.exitCode)) throw new Error('run exitCode must be a safe integer');\n  const started = timestamp(run.startedAt, 'startedAt');\n  const completed = timestamp(run.completedAt, 'completedAt');\n  if (completed < started) throw new Error('run completedAt precedes startedAt');\n  if (\n    run.buildEvidence !== undefined\n    && run.buildEvidence.sourceStateId !== run.sourceState.sourceStateId\n  ) {\n    throw new Error('build evidence belongs to a different source state');\n  }\n}\n\n/**","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/harness/in-memory-run-receipt-reference.ts#L5-L41","documentation":"validateRun requires run.executionId, run.sessionId, and run.workloadId to be non-blank: each must trim to a non-empty string before the ledger records anything. These identities tie receipts to the harness session/workload coordination model, so blank values would make evidence unattributable. Any one of the three failing triggers the same message.","triggerScenarios":"recordRun with executionId: '', sessionId: '   ', or workloadId: '' — typically from default parameters (id = ''), spreads of optional config where the field was never set, or IDs built from template strings whose variables were undefined.","commonSituations":"Test fixtures copied without filling IDs; refactors that rename fields and leave the old ones empty; defaults like `executionId = opts.executionId ?? ''`; IDs derived from env vars that are unset in CI.","solutions":["Populate all three with real identifiers: crypto.randomUUID() per execution attempt, stable IDs for session and workload","Pre-validate: [run.executionId, run.sessionId, run.workloadId].every((id) => typeof id === 'string' && id.trim().length > 0)","Fail fast where RunEvidence is constructed instead of letting the ledger reject it downstream"],"exampleFix":"// before\nreceipt.recordRun({ executionId: '', sessionId: 'sess', workloadId: 'wl', /* ... */ });\n\n// after\nreceipt.recordRun({ executionId: crypto.randomUUID(), sessionId: 'sess', workloadId: 'wl', /* ... */ });","handlingStrategy":"validation","validationCode":"function hasRunIdentity(run: { executionId: string; sessionId: string; workloadId: string }): boolean {\n  return [run.executionId, run.sessionId, run.workloadId]\n    .every((id) => typeof id === 'string' && id.trim().length > 0);\n}","typeGuard":"function isIdentifiedRun(run: unknown): run is { executionId: string; sessionId: string; workloadId: string } {\n  if (typeof run !== 'object' || run === null) return false;\n  const r = run as Record<string, unknown>;\n  return ['executionId', 'sessionId', 'workloadId'].every((k) => typeof r[k] === 'string' && (r[k] as string).trim().length > 0);\n}","tryCatchPattern":"try {\n  ledger.recordRun(run);\n} catch (error) {\n  if (error instanceof Error && error.message === 'run execution, session, and workload identity are required') {\n    throw new Error(`refusing to record anonymous run: fill executionId/sessionId/workloadId (got ${JSON.stringify({ e: run.executionId, s: run.sessionId, w: run.workloadId })})`);\n  }\n  throw error;\n}","preventionTips":["Mint executionId with crypto.randomUUID() per attempt; never default identifiers to ''","Validate the three identity fields where RunEvidence is built, not at the ledger","Type the constructor arguments so undefined IDs are compile-time errors"],"tags":["validation","required-fields","run-receipt","identifier"],"backgroundTag":"missing-required-argument","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}