affaan-m/ECC · error · RetrospectiveError
retrospective.mixed_task_families
retrospective.mixed_task_families
Error message
all capsules must have the same task family
What it means
A retrospective can only group capsules from one task family, since the report aggregates runs of comparable tasks. After reading projections, groupCapsules takes the first capsule's task_family and requires every other capsule to match; the first mismatched input (by index) triggers this error. This prevents statistically meaningless comparisons across unrelated task families.
Solutions
- Group only capsules that share the same task_family; run a separate retrospective per family
- Regenerate the mismatched capsules with the correct task family label
- Check each capsule's projection task_family before grouping
- If the family was renamed, re-label or re-record old capsules so families align
Example fix
// before node scripts/eval-harness.js capsule group ./caps-fix-1 ./caps-feature-1 // mixed families // after node scripts/eval-harness.js capsule group ./caps-fix-1 ./caps-fix-2 // one family per run
Defensive patterns
Strategy: validation
Validate before calling
// read task_family from each capsule's projection metadata before grouping
const families = new Set(dirs.map(d => readCapsuleFamily(d)));
if (families.size > 1) throw new Error(`mixed task families: ${[...families].join(', ')}`); Try / catch
try { groupCapsules(dirs); } catch (e) { if (e.code === 'retrospective.mixed_task_families') console.error(`capsule #${e.index} is from a different task family; group per family`); throw e; } Prevention
- Keep one retrospective per task family
- Verify task_family labels when adopting capsules from other repos or harness versions
- Rename directories or re-record capsules after a task_family rename
- Group capsules by family programmatically before calling groupCapsules
When it happens
Trigger: Calling groupCapsules with directories whose capsules were produced for different task families, e.g. mixing 'fix-bug' family capsules with 'add-feature' family capsules; passing capsules from differently named task families after a rename.
Common situations: Aggregating snapshots across repos or task types; a task_family label change in the harness between snapshot generations; copy-pasting a capsule group command that still references directories from a previous, different-family experiment.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/d37b01bdafd0057c.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/eval-harness/retrospective.js:74
}
/**
* Group up to 100 selected snapshots of one task family by harness_version.
* Duplicate identities count once only if the verified projections match.
* Different checkpoints of the same identity are ambiguous and refused.
* Does not read saved projections, copy payloads, write files or invoke tools.
*/
function groupCapsules(dirs) {
if (!Array.isArray(dirs) || dirs.length < 1 || dirs.length > MAX_INPUTS
|| !Array.from(dirs).every(dir => typeof dir === 'string' && dir.trim() && !dir.includes('\0'))) {
throw new RetrospectiveError('retrospective.invalid_inputs', `supply 1 to ${MAX_INPUTS} capsule directory paths`);
}
const projections = dirs.map(readProjection);
const family = projections[0].task_family;
const unique = new Map();
for (const [index, projection] of projections.entries()) {
if (projection.task_family !== family) {
throw new RetrospectiveError('retrospective.mixed_task_families', 'all capsules must have the same task family', index);
}
const key = identity(projection);
const previous = unique.get(key);
if (previous && previous.projection_hash !== projection.projection_hash) {
throw new RetrospectiveError('retrospective.conflicting_identity', 'conflicting snapshots share a capsule identity', index);
}
unique.set(key, projection);
}
const byHarness = new Map();
for (const projection of unique.values()) {
const version = projection.harness_version;
byHarness.set(version, [...(byHarness.get(version) || []), projection]);
}
const report = {
schema: 'capsule-retrospective/v1',
report_only: true,
task_family: family,
input_count: dirs.length,View on GitHub (pinned to 8321021c54)