{"record":{"id":"b1d58d80a129bd47","repo":"affaan-m/ECC","slug":"user-feedback-must-be-accepted-corrected-rejecte","errorCode":null,"errorMessage":"user_feedback must be accepted, corrected, rejected, or null","messagePattern":"user_feedback must be accepted, corrected, rejected, or null","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/tracker.js","lineNumber":74,"sourceCode":"\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\n  return {\n    skill_id: skillId,\n    skill_version: skillVersion,\n    task_description: taskDescription,\n    outcome,\n    failure_reason: input.failure_reason || input.failureReason || null,\n    tokens_used: toNullableNumber(input.tokens_used ?? input.tokensUsed, 'tokens_used'),\n    duration_ms: toNullableNumber(input.duration_ms ?? input.durationMs, 'duration_ms'),\n    user_feedback: userFeedback,\n    recorded_at: recordedAt,\n  };\n}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/skill-evolution/tracker.js#L56-L92","documentation":"normalizeExecutionRecord validates userFeedback against VALID_FEEDBACK and throws 'user_feedback must be accepted, corrected, rejected, or null' when a non-null value outside that set is supplied. userFeedback is optional but must be either null/omitted or exactly one of the three recognized feedback values.","triggerScenarios":"Calling record() with userFeedback set to 'yes', 'good', 'ok', a boolean, an empty string, or any other value not in {'accepted','corrected','rejected'} while also not being null.","commonSituations":"Prompt-driven scripts capturing free-text user sentiment and passing it straight through; mapping thumbs-up/down booleans onto the field instead of choosing an enum value; typos like 'accepted!' or 'accept'; older scripts written before the feedback field existed passing an incompatible default.","solutions":["Pass one of 'accepted', 'corrected', 'rejected' (lowercase) or explicitly null.","Translate UI-level feedback (booleans, ratings) into the three enum values before recording.","Omit the field or pass null when no user feedback was collected, instead of inventing a placeholder value."],"exampleFix":"// before\ntracker.record({ skillId, skillVersion, taskDescription, outcome, userFeedback: 'yes' });\n\n// after\nconst userFeedback = userReverted ? 'rejected' : userEdited ? 'corrected' : userApproved ? 'accepted' : null;\ntracker.record({ skillId, skillVersion, taskDescription, outcome, userFeedback });","handlingStrategy":"validation","validationCode":"const VALID_FEEDBACK = new Set(['accepted', 'corrected', 'rejected']);\nfunction assertUserFeedback(userFeedback) {\n  if (userFeedback !== null && !VALID_FEEDBACK.has(userFeedback)) {\n    throw new Error('user_feedback must be accepted, corrected, rejected, or null');\n  }\n}","typeGuard":"function isValidUserFeedback(v) {\n  return v === null || v === 'accepted' || v === 'corrected' || v === 'rejected';\n}","tryCatchPattern":"try {\n  tracker.record(record);\n} catch (err) {\n  if (err.message.startsWith('user_feedback must be')) {\n    console.error(`Invalid user_feedback \"${record.userFeedback}\"; use accepted | corrected | rejected | null.`);\n    process.exitCode = 1;\n    return;\n  }\n  throw err;\n}","preventionTips":["Treat absence of feedback as null, never as an empty string or placeholder word.","Convert UI signals (booleans, ratings, free text) into the three enum values at the collection point.","Reuse one mapping function for feedback translation so all callers produce identical enum values."],"tags":["validation","enum","skill-evolution"],"backgroundTag":"invalid-enum-value","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"}