{"record":{"id":"939cb20618ccaa61","repo":"affaan-m/ECC","slug":"skill-version-is-required","errorCode":null,"errorMessage":"skill_version is required","messagePattern":"skill_version is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/tracker.js","lineNumber":62,"sourceCode":"\nfunction normalizeExecutionRecord(input, options = {}) {\n  if (!input || typeof input !== 'object' || Array.isArray(input)) {\n    throw new Error('skill execution payload must be an object');\n  }\n\n  const skillId = input.skill_id || input.skillId;\n  const skillVersion = input.skill_version || input.skillVersion;\n  const taskDescription = input.task_description || input.task_attempted || input.taskAttempted;\n  const outcome = input.outcome;\n  const recordedAt = input.recorded_at || options.now || new Date().toISOString();\n  const userFeedback = input.user_feedback || input.userFeedback || null;\n\n  if (typeof skillId !== 'string' || skillId.trim().length === 0) {\n    throw new Error('skill_id is required');\n  }\n\n  if (typeof skillVersion !== 'string' || skillVersion.trim().length === 0) {\n    throw new Error('skill_version is required');\n  }\n\n  if (typeof taskDescription !== 'string' || taskDescription.trim().length === 0) {\n    throw new Error('task_description is required');\n  }\n\n  if (!VALID_OUTCOMES.has(outcome)) {\n    throw new Error('outcome must be one of success, failure, or partial');\n  }\n\n  if (userFeedback !== null && !VALID_FEEDBACK.has(userFeedback)) {\n    throw new Error('user_feedback must be accepted, corrected, rejected, or null');\n  }\n\n  if (Number.isNaN(Date.parse(recordedAt))) {\n    throw new Error('recorded_at must be an ISO timestamp');\n  }\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/skill-evolution/tracker.js#L44-L80","documentation":"normalizeExecutionRecord() requires a skill_version string on every execution record, read from input.skill_version or input.skillVersion. Missing, non-string, or empty/whitespace-only values throw 'skill_version is required'. Version is mandatory so executions can be attributed to the exact skill iteration when evaluating skill evolution.","triggerScenarios":"record({ skill_id: 'lint-repo', task_description: 'x', outcome: 'success' }) with no version key; skill_version: '' after a trim; skill_version read from a skill manifest that lacks a version field and therefore came through as undefined.","commonSituations":"Skills authored without a version in frontmatter/metadata so callers have nothing to pass; pipelines where the version key was renamed (e.g. 'v' or 'version'); forgetting to bump/pass the version after a skill update; both snake_case and camelCase keys absent in a hand-built payload.","solutions":["Include a non-empty skill_version string: record({ skill_id, skill_version: '1.0.0', ... }).","Read the version from the skill's metadata/frontmatter and pass it explicitly; add a version to skills missing one.","If your field is named 'version' or 'v', map it to skill_version (or skillVersion) before calling.","Default to a known constant (e.g. '0.0.0' or from package.json) only if unversioned skills are acceptable in your analytics."],"exampleFix":"// before\nrecord({ skill_id: 'lint-repo', task_description: 'lint repo', outcome: 'success' });\n\n// after\nrecord({ skill_id: 'lint-repo', skill_version: skill.metadata.version ?? '0.0.0', task_description: 'lint repo', outcome: 'success' });","handlingStrategy":"validation","validationCode":"function assertSkillVersion(payload) {\n  const v = payload?.skill_version ?? payload?.skillVersion;\n  if (typeof v !== 'string' || v.trim().length === 0) {\n    throw new TypeError('execution payload missing non-empty skill_version');\n  }\n  return v.trim();\n}","typeGuard":"function hasSkillVersion(input) {\n  const v = input?.skill_version ?? input?.skillVersion;\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  tracker.record(payload);\n} catch (err) {\n  if (err.message === 'skill_version is required') {\n    console.error('Execution payload missing skill_version; read it from skill metadata before recording');\n    return;\n  }\n  throw err;\n}","preventionTips":["Always read skill_version from the skill's frontmatter/metadata when building payloads.","Require a version field in skill authoring templates so it is never absent.","Apply a safe default (e.g. '0.0.0') in your recording adapter for unversioned skills."],"tags":["skill-evolution","validation","required-field"],"backgroundTag":"missing-required-argument","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}