affaan-m/ECC · error · Error
task_description is required
Error message
task_description is required
What it means
normalizeExecutionRecord in scripts/lib/skill-evolution/tracker.js validates every field of an execution record before persisting it. It throws 'task_description is required' when the taskDescription argument is not a non-empty string (missing, non-string, or whitespace-only). The library refuses to record executions without a human-readable description of the task performed.
Solutions
- Pass a non-empty descriptive string as the taskDescription argument to record()/normalizeExecutionRecord.
- If the value comes from CLI/env/config, default or trim it before calling: (raw ?? '').trim() and fall back to a meaningful label if empty.
- If a structured object was passed by mistake, serialize the relevant fields to a string first (e.g. JSON.stringify or a formatter).
Example fix
// before
tracker.record({ skillId, skillVersion, taskDescription: undefined, outcome: 'success' });
// after
const taskDescription = (process.argv.find(a => a.startsWith('--task='))?.slice(7) ?? 'unspecified task').trim();
tracker.record({ skillId, skillVersion, taskDescription, outcome: 'success' }); Defensive patterns
Strategy: validation
Validate before calling
function assertTaskDescription(taskDescription) {
if (typeof taskDescription !== 'string' || taskDescription.trim().length === 0) {
throw new Error('task_description must be a non-empty string before calling record()');
}
} Type guard
function hasTaskDescription(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
tracker.record(record);
} catch (err) {
if (err.message === 'task_description is required') {
console.error('Execution record missing task_description; supply a non-empty string describing the task.');
process.exitCode = 1;
return;
}
throw err;
} Prevention
- Build execution records through a single factory function that requires and trims taskDescription.
- Default missing descriptions to a derived label (e.g. the skill name plus command) instead of letting undefined through.
- Trim user-supplied text so whitespace-only input cannot slip through.
When it happens
Trigger: Calling record() (or normalizeExecutionRecord directly) with taskDescription undefined/null, with a non-string value (e.g. an object from a parsed options bag), or with a whitespace-only string like '' or ' '.
Common situations: Hook scripts building the record from CLI args or env vars that omit --task-description; programmatically constructing the record object and forgetting the field; upstream tools that pass structured task metadata instead of a string; templated scripts where the placeholder was never filled in.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- skill_id is required
- skill_version is required
- a confirmed nonempty coordinate is required
- must be a number
- outcome must be one of success, failure, or partial
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/6e9b07e8c6603bbe.
Report an issue: GitHub.
Appendix: 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 8321021c54)