Yeachan-Heo/oh-my-codex · error · Error
Invalid Autopilot context timestamp: ${nowIso}
Error message
Invalid Autopilot context timestamp: ${nowIso} What it means
Thrown by utcCompactTimestamp in the Autopilot keyword detector hook when the nowIso timestamp passed into the context snapshot flow cannot be parsed by new Date() (NaN time). The hook formats timestamps into a compact UTC form for snapshot filenames and refuses invalid date strings.
Source
Thrown at src/hooks/keyword-detector.ts:253
question_enforcement?: DeepInterviewQuestionEnforcementState;
[key: string]: unknown;
}
function slugifyAutopilotTask(text: string): string {
const slug = text
.replace(/(?:^|\s)\$?(?:oh-my-codex:)?autopilot\b/gi, ' ')
.replace(/[^A-Za-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
.toLowerCase()
.slice(0, 48)
.replace(/-+$/g, '');
return slug || 'autopilot-task';
}
function utcCompactTimestamp(nowIso: string): string {
const parsed = new Date(nowIso);
if (Number.isNaN(parsed.getTime())) {
throw new Error(`Invalid Autopilot context timestamp: ${nowIso}`);
}
return parsed.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}Z$/, 'Z');
}
function isSafeAutopilotContextSnapshotPath(value: unknown): value is string {
const path = safeString(value).trim();
const contextPrefix = '.omx/context/';
const snapshotName = path.startsWith(contextPrefix) ? path.slice(contextPrefix.length) : '';
return path.startsWith('.omx/context/')
&& path.endsWith('.md')
&& !isAbsolute(path)
&& !path.split('/').includes('..')
&& !path.includes('\\')
&& snapshotName !== ''
&& !snapshotName.includes('/');
}
function isAutopilotRecoverySnapshotPath(path: string): boolean {View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Pass a value produced by new Date().toISOString() directly without reformatting
- Fix the upstream producer of nowIso to emit strict ISO-8601 (YYYY-MM-DDTHH:mm:ss.sssZ)
- In tests, generate timestamps with new Date().toISOString() instead of hardcoding plausible-looking strings
Example fix
// before
detectKeyword(text, { nowIso: '20260827T120000Z' });
// after
detectKeyword(text, { nowIso: new Date().toISOString() }); Defensive patterns
Strategy: validation
Validate before calling
function isValidIso(value: string): boolean {
return !Number.isNaN(new Date(value).getTime());
}
const safeIso = isValidIso(nowIso) ? nowIso : new Date().toISOString(); Type guard
function isIsoDateString(v: unknown): v is string {
return typeof v === 'string' && !Number.isNaN(new Date(v).getTime());
} Try / catch
try { detectKeyword(text, { nowIso }); } catch (err) {
if ((err as Error).message.startsWith('Invalid Autopilot context timestamp')) {
return detectKeyword(text, { nowIso: new Date().toISOString() });
}
throw err;
} Prevention
- Always pass new Date().toISOString() output verbatim
- Type the nowIso parameter as a branded ISO string in your own wrappers
- In tests, generate timestamps dynamically instead of hardcoding strings
When it happens
Trigger: Passing nowIso values like 'not-a-date', '' (empty string is invalid), '2026-13-45', or an already-compact form like '20260827T120000Z' that Date can't parse, into the Autopilot context snapshot path.
Common situations: Test fixtures with hand-written timestamp strings; pipeline code reformatting the ISO string before passing it (double-formatting); clock mocks returning undefined/null that stringifies to 'undefined'; locale-specific date strings.
Related errors
- autoresearch candidate artifact created_at is required
- Invalid --after timestamp: ${value}
- invalid auth slot path
- Autoresearch goal ${mission.slug} cannot complete until prof
- autoresearch candidate artifact notes must be a string array
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/a688c951060c6bb6.
Report an issue: GitHub.