affaan-m/ECC · error · Error
recorded_at must be an ISO timestamp
Error message
recorded_at must be an ISO timestamp
What it means
normalizeExecutionRecord parses recordedAt with Date.parse and throws 'recorded_at must be an ISO timestamp' when the result is NaN. The library requires an ISO 8601 timestamp so records can be sorted and analyzed chronologically.
Solutions
- Generate the timestamp with new Date().toISOString() (e.g. '2026-09-16T10:00:00.000Z') instead of manual formatting.
- If you have a Date object, convert it: date.toISOString().
- If input is a raw string, normalize it first: new Date(raw).toISOString(), guarding against Invalid Date.
Example fix
// before
tracker.record({ skillId, skillVersion, taskDescription, outcome, recordedAt: '16/09/2026 10:00' });
// after
tracker.record({ skillId, skillVersion, taskDescription, outcome, recordedAt: new Date().toISOString() }); Defensive patterns
Strategy: validation
Validate before calling
function assertIsoTimestamp(recordedAt) {
if (typeof recordedAt !== 'string' || Number.isNaN(Date.parse(recordedAt))) {
throw new Error('recorded_at must be an ISO 8601 timestamp string, e.g. new Date().toISOString()');
}
} Type guard
function isIsoTimestamp(v) {
return typeof v === 'string' && !Number.isNaN(Date.parse(v));
} Try / catch
try {
tracker.record(record);
} catch (err) {
if (err.message === 'recorded_at must be an ISO timestamp') {
console.error(`Bad recorded_at "${record.recordedAt}"; regenerate with new Date().toISOString().`);
process.exitCode = 1;
return;
}
throw err;
} Prevention
- Always generate timestamps with new Date().toISOString(); never hand-format dates.
- Never pass Date objects where strings are expected; convert with toISOString().
- Avoid locale-dependent date commands in shell scripts; use date -u +%Y-%m-%dT%H:%M:%SZ for UTC ISO output.
When it happens
Trigger: Passing recordedAt as a non-date string (e.g. 'yesterday', '16/09/2026'), a Date object instead of a string, an empty string, or a locale-formatted date that Date.parse cannot interpret in the runtime environment.
Common situations: Shell scripts inserting $(date) output in a non-ISO locale format; hand-written timestamps like '2026-09-16 10:00' without seconds/timezone on strict engines; forgetting to call toISOString() on a Date object and passing the object itself; locale-dependent date formatting differing between CI and local machines.
Related errors
- must be a number
- Invalid now timestamp
- Invalid now timestamp
- must be an ISO-8601 timestamp.
- 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/0aa5e8c4f590c350.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/skill-evolution/tracker.js:78
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'),
user_feedback: userFeedback,
recorded_at: recordedAt,
};
}
function readJsonl(filePath) {
if (!fs.existsSync(filePath)) {
return [];View on GitHub (pinned to 8321021c54)