ruvnet/ruflo · error · Error

run execution, session, and workload identity are required

Error message

run execution, session, and workload identity are required

What it means

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.

Source

Thrown at v3/@claude-flow/codex/src/harness/in-memory-run-receipt-reference.ts:23

const DIGEST = /^sha256:[0-9a-f]{64}$/;

function sha256(value: string): string {
  return `sha256:${createHash('sha256').update(value).digest('hex')}`;
}

function copy<T>(value: T): T {
  return structuredClone(value);
}

function timestamp(value: string, label: string): number {
  const parsed = Date.parse(value);
  if (!Number.isFinite(parsed)) throw new Error(`${label} must be an ISO timestamp`);
  return parsed;
}

function validateRun(run: RunEvidence): void {
  if (!run.executionId.trim() || !run.sessionId.trim() || !run.workloadId.trim()) {
    throw new Error('run execution, session, and workload identity are required');
  }
  if (!DIGEST.test(run.sourceState.sourceStateId)) throw new Error('run sourceStateId is invalid');
  if (!DIGEST.test(run.commandDigest) || !DIGEST.test(run.evidenceDigest)) {
    throw new Error('run command and evidence digests must be canonical sha256 values');
  }
  if (!Number.isSafeInteger(run.exitCode)) throw new Error('run exitCode must be a safe integer');
  const started = timestamp(run.startedAt, 'startedAt');
  const completed = timestamp(run.completedAt, 'completedAt');
  if (completed < started) throw new Error('run completedAt precedes startedAt');
  if (
    run.buildEvidence !== undefined
    && run.buildEvidence.sourceStateId !== run.sourceState.sourceStateId
  ) {
    throw new Error('build evidence belongs to a different source state');
  }
}

/**

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Populate all three with real identifiers: crypto.randomUUID() per execution attempt, stable IDs for session and workload
  2. Pre-validate: [run.executionId, run.sessionId, run.workloadId].every((id) => typeof id === 'string' && id.trim().length > 0)
  3. Fail fast where RunEvidence is constructed instead of letting the ledger reject it downstream

Example fix

// before
receipt.recordRun({ executionId: '', sessionId: 'sess', workloadId: 'wl', /* ... */ });

// after
receipt.recordRun({ executionId: crypto.randomUUID(), sessionId: 'sess', workloadId: 'wl', /* ... */ });
Defensive patterns

Strategy: validation

Validate before calling

function hasRunIdentity(run: { executionId: string; sessionId: string; workloadId: string }): boolean {
  return [run.executionId, run.sessionId, run.workloadId]
    .every((id) => typeof id === 'string' && id.trim().length > 0);
}

Type guard

function isIdentifiedRun(run: unknown): run is { executionId: string; sessionId: string; workloadId: string } {
  if (typeof run !== 'object' || run === null) return false;
  const r = run as Record<string, unknown>;
  return ['executionId', 'sessionId', 'workloadId'].every((k) => typeof r[k] === 'string' && (r[k] as string).trim().length > 0);
}

Try / catch

try {
  ledger.recordRun(run);
} catch (error) {
  if (error instanceof Error && error.message === 'run execution, session, and workload identity are required') {
    throw new Error(`refusing to record anonymous run: fill executionId/sessionId/workloadId (got ${JSON.stringify({ e: run.executionId, s: run.sessionId, w: run.workloadId })})`);
  }
  throw error;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/67eeb45434d2bc00. Report an issue: GitHub.