affaan-m/ECC · error
task_description is required
Error message
task_description is required
What it means
Thrown by normalizeExecutionRecord when task_description is missing. The field accepts three aliases in priority order: task_description, task_attempted, taskAttempted. All must resolve to a non-empty trimmed string.
Source
Thrown at scripts/lib/skill-evolution/tracker.js:66
}
const skillId = input.skill_id || input.skillId;
const skillVersion = input.skill_version || input.skillVersion;
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,View on GitHub (pinned to 01e15490f0)
Solutions
- Provide task_description (or task_attempted / taskAttempted) as a non-empty string.
- Capture the user's prompt or a summary before invoking recordSkillRun.
- If the task is genuinely empty, require a placeholder description rather than skipping.
Example fix
// before
recordSkillRun({ skill_id, skill_version, outcome: 'success' });
// after
recordSkillRun({ skill_id, skill_version, task_description: prompt || '(no description)', outcome: 'success' }); Defensive patterns
Strategy: validation
Validate before calling
function resolveTask(input) {
const t = input.task_description || input.task_attempted || input.taskAttempted;
if (typeof t !== 'string' || t.trim().length === 0) {
throw new TypeError('task_description missing');
}
return t;
} Type guard
function hasTaskDescription(input) {
const t = input?.task_description || input?.task_attempted || input?.taskAttempted;
return typeof t === 'string' && t.trim().length > 0;
} Try / catch
try {
recordSkillRun(input);
} catch (err) {
if (/task_description is required/.test(err.message)) { input.task_description = '(untitled)'; recordSkillRun(input); }
else throw err;
} Prevention
- Capture the user's prompt or a summary at invocation time.
- Disallow empty descriptions in the recording UI.
- Reuse the same alias consistently (task_description preferred).
When it happens
Trigger: recordSkillRun({ skill_id, skill_version, outcome }) with none of task_description/task_attempted/taskAttempted; all aliases empty/whitespace.
Common situations: Recording a run without capturing what was attempted; using yet another alias name (e.g. task) that the normalizer does not recognize; empty task string from a UI.
Related errors
- skill_id is required
- skill_version is required
- memory body must contain non-whitespace context.
- target harnesses must contain at least one harness or "all".
- Memory document ${sourcePath} is missing fields: ${missing.j
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/6e9b07e8c6603bbe.
Report an issue: GitHub.