JuliusBrussee/caveman · error · Error
${where} causal slice references a workflow variant that is
Error message
${where} causal slice references a workflow variant that is not in this report What it means
item.causal_slice.variant_id must resolve against the report's workflow_variants map (validate-continuous-improvement.mjs:171-173). The causal slice is a subgraph of a variant this report carries; a dangling id — typo, deleted variant, or an id from another fixture — fails here before any node or edge checking begins.
Source
Thrown at packages/shared/contracts/scripts/validate-continuous-improvement.mjs:173
throw new Error(`${where} cohort arms (${comparedUnits}) plus exclusions (${excluded}) do not account for its ${item.cohort.family_unit_count} family units`);
}
const selectedPerArm = new Map();
for (const trace of item.representative_traces) {
const variant = armVariants.get(trace.arm);
if (!variant || variant.id !== trace.variant_id) throw new Error(`${where} representative trace names a variant that is not that arm's variant`);
if (!unitsByID.has(trace.analysis_unit_id)) throw new Error(`${where} representative trace ${trace.analysis_unit_id} is not an analysis unit of this report`);
if (!familyUnits.has(trace.analysis_unit_id)) throw new Error(`${where} representative trace ${trace.analysis_unit_id} is not a member of the cohort's task family`);
if (!variant.analysis_unit_ids.includes(trace.analysis_unit_id)) throw new Error(`${where} representative trace ${trace.analysis_unit_id} did not run that arm's workflow variant`);
selectedPerArm.set(trace.arm, (selectedPerArm.get(trace.arm) ?? 0) + 1);
}
for (const [arm, count] of selectedPerArm) {
if (count > 3) throw new Error(`${where} arm ${arm} carries ${count} representative traces, more than three`);
}
const slice = item.causal_slice;
const sliceVariant = variantsByID.get(slice.variant_id);
if (!sliceVariant) throw new Error(`${where} causal slice references a workflow variant that is not in this report`);
if (sliceVariant.id !== armVariants.get("baseline").id) throw new Error(`${where} causal slice is not taken from the baseline arm's variant`);
const sliceNodes = new Set(sliceVariant.nodes.map((node) => node.id));
if (slice.manifestation_node_id !== "" && !sliceNodes.has(slice.manifestation_node_id)) {
throw new Error(`${where} manifestation node ${slice.manifestation_node_id} is not a node of variant ${sliceVariant.id}`);
}
if (item.diagnosis.manifestation.node_id !== slice.manifestation_node_id) {
throw new Error(`${where} diagnosis manifestation node disagrees with its causal slice`);
}
for (const nodeID of slice.node_chain) {
if (!sliceNodes.has(nodeID)) throw new Error(`${where} causal slice node ${nodeID} is not a node of variant ${sliceVariant.id}`);
}
if (slice.manifestation_node_id !== "" && !slice.node_chain.includes(slice.manifestation_node_id)) {
throw new Error(`${where} causal slice omits its own manifestation node`);
}
const provenDependency = (edge) => edge.strength === "hard" && (edge.type === "data" || edge.type === "control") && edge.evidence_refs.length > 0;
const variantEdges = new Map(sliceVariant.edges.map((edge) => [`${edge.from} ${edge.to} ${edge.type}`, edge]));
for (const edge of slice.hard_edges) {
if (!provenDependency(edge)) throw new Error(`${where} hard chain carries an unproven edge ${edge.from}->${edge.to}`);View on GitHub (pinned to 766dce6b13)
Solutions
- Set causal_slice.variant_id to a variant id that exists in this report — specifically the baseline arm's variant (see error 614).
- If the variant object was removed, restore it to workflow_variants.
- Regenerate the case rather than cloning, then re-run the validator.
Example fix
// before
"causal_slice": { "variant_id": "wf-build-9", ... }
// after — the baseline arm's variant in this report
"causal_slice": { "variant_id": "wf-build-01", ... } Defensive patterns
Strategy: validation
Validate before calling
const danglingSliceVariants = (report) => {
const ids = new Set(report.workflow_variants.map((v) => v.id));
return report.cases.filter((c) => !ids.has(c.causal_slice.variant_id)).map((c) => c.id);
}; Try / catch
try {
execFileSync(process.execPath, [VALIDATOR, reportPath, spansPath]);
} catch (err) {
if (/causal slice references a workflow variant/.test(err.message)) {
failCI(`slice variant id not in this report: ${err.message}`);
} else throw err;
} Prevention
- Derive causal_slice.variant_id from the baseline arm in the generator instead of typing it.
- Keep slices and their variants in the same fixture file.
- When cloning a case as a template, the slice variant id is the first thing to rewrite.
When it happens
Trigger: The slice block was copied from another case or fixture with a different variant id; the variant was renamed; slice.variant_id was left as a placeholder while hand-authoring a case.
Common situations: Template-based fixture authoring; refactors that rename variant ids; cases cloned as starting points and only partially adapted.
Related errors
- ${where} manifestation node ${slice.manifestation_node_id} i
- ${where} causal slice node ${nodeID} is not a node of varian
- ${where} cohort references a task family that is not in this
- ${where} cohort arm ${arm.role} references a workflow varian
- ${where} cohort arm ${arm.role} uses a variant of another ta
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/73b9f50e1f76d15d.
Report an issue: GitHub.