affaan-m/ECC · error · Error

outcome must be one of success, failure, or partial

Error message

outcome must be one of success, failure, or partial

What it means

normalizeExecutionRecord validates the outcome field against VALID_OUTCOMES and throws 'outcome must be one of success, failure, or partial' when the value is outside that set. The tracker only supports three canonical outcomes so downstream analysis can group execution records reliably.

Solutions

  1. Use exactly one of 'success', 'failure', or 'partial' (lowercase) as the outcome value.
  2. Normalize upstream statuses before calling: map runner results onto the three allowed values.
  3. If you need additional outcome categories, extend VALID_OUTCOMES in tracker.js and its consumers deliberately, not ad hoc.

Example fix

// before
tracker.record({ skillId, skillVersion, taskDescription, outcome: 'passed' });

// after
const outcome = testsFailed ? 'failure' : fixesApplied ? 'partial' : 'success';
tracker.record({ skillId, skillVersion, taskDescription, outcome });
Defensive patterns

Strategy: validation

Validate before calling

const VALID_OUTCOMES = new Set(['success', 'failure', 'partial']);
function assertOutcome(outcome) {
  if (!VALID_OUTCOMES.has(outcome)) {
    throw new Error(`outcome must be one of success, failure, or partial (got ${JSON.stringify(outcome)})`);
  }
}

Type guard

function isValidOutcome(v) {
  return v === 'success' || v === 'failure' || v === 'partial';
}

Try / catch

try {
  tracker.record(record);
} catch (err) {
  if (err.message.startsWith('outcome must be one of')) {
    console.error(`Invalid outcome "${record.outcome}"; use success | failure | partial.`);
    process.exitCode = 1;
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling record() with outcome values like 'ok', 'SUCCESS', 'passed', 'error', true/false, or omitting outcome entirely (undefined).

Common situations: Mapping another tool's status vocabulary onto the tracker without translating (e.g. 'passed'/'failed' from a test runner); case-sensitivity mistakes ('Success'); shell scripts quoting or casing the flag incorrectly; newer callers assuming more outcome categories exist.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/ad97df5595b8e0c7. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/skill-evolution/tracker.js:70

  const taskDescription = input.task_description || input.task_attempted || input.taskAttempted;
  const outcome = input.outcome;
  const recordedAt = input.recorded_at || options.now || new Date().toISOString();
  const userFeedback = input.user_feedback || input.userFeedback || null;

  if (typeof skillId !== 'string' || skillId.trim().length === 0) {
    throw new Error('skill_id is required');
  }

  if (typeof skillVersion !== 'string' || skillVersion.trim().length === 0) {
    throw new Error('skill_version is required');
  }

  if (typeof taskDescription !== 'string' || taskDescription.trim().length === 0) {
    throw new Error('task_description is required');
  }

  if (!VALID_OUTCOMES.has(outcome)) {
    throw new Error('outcome must be one of success, failure, or partial');
  }

  if (userFeedback !== null && !VALID_FEEDBACK.has(userFeedback)) {
    throw new Error('user_feedback must be accepted, corrected, rejected, or null');
  }

  if (Number.isNaN(Date.parse(recordedAt))) {
    throw new Error('recorded_at must be an ISO timestamp');
  }

  return {
    skill_id: skillId,
    skill_version: skillVersion,
    task_description: taskDescription,
    outcome,
    failure_reason: input.failure_reason || input.failureReason || null,
    tokens_used: toNullableNumber(input.tokens_used ?? input.tokensUsed, 'tokens_used'),
    duration_ms: toNullableNumber(input.duration_ms ?? input.durationMs, 'duration_ms'),

View on GitHub (pinned to 8321021c54)