can1357/oh-my-pi · error · RangeError
Invalid query time
Error message
Invalid query time
What it means
This is recall.ts's own parseQueryTime guard for the `queryTime` option: a Date whose getTime() is not finite is rejected with a RangeError. It mirrors helpers.normalizeDateUtc but lives in the recall scoring path so decay/boost math never receives NaN time.
Source
Thrown at packages/mnemopi/src/core/beam/recall.ts:400
}
}
}
return clamp01((exact + partial * 0.5) / queryTokens.length);
}
function recencyDecay(timestamp: unknown, halfLifeHours = 72): number {
const raw = asString(timestamp);
if (raw.length === 0) return 0;
const parsed = Date.parse(raw);
if (!Number.isFinite(parsed)) return 0;
const ageHours = Math.max(0, (Date.now() - parsed) / 3_600_000);
return Math.exp(-ageHours / Math.max(halfLifeHours, 0.001));
}
export function parseQueryTime(value: RecallOptionsInternal["queryTime"]): Date {
if (value == null) return new Date();
if (value instanceof Date) {
if (!Number.isFinite(value.getTime())) throw new RangeError("Invalid query time");
return value;
}
if (typeof value === "string") {
const normalized = /^\d{4}-\d{2}-\d{2}$/.test(value)
? `${value}T00:00:00.000Z`
: /(?:Z|[+-]\d{2}:?\d{2})$/.test(value)
? value
: `${value}Z`;
const parsed = new Date(normalized);
if (Number.isFinite(parsed.getTime())) return parsed;
}
throw new TypeError("queryTime must be null, an ISO date string, or a valid Date");
}
export function temporalBoost(timestamp: unknown, queryTime: Date, halfLifeHours: number): number {
const raw = asString(timestamp);
if (raw.length === 0) return 0;
const parsed = Date.parse(raw);View on GitHub (pinned to 9690622007)
Solutions
- Check `Number.isFinite(d.getTime())` before assigning the Date to queryTime.
- Pass an ISO string (YYYY-MM-DD or full ISO with Z) instead of a Date when the source is text.
- Fix the upstream construction: use Date.now() or a validated parse for the source value.
Example fix
// before
const qt = new Date(record.timestamp); // record.timestamp missing -> Invalid Date
recall(query, { queryTime: qt });
// after
const qt = new Date(record.timestamp);
if (Number.isNaN(qt.getTime())) qt = new Date(); // fall back to now
recall(query, { queryTime: qt }); Defensive patterns
Strategy: validation
Validate before calling
if (queryTime instanceof Date && !Number.isFinite(queryTime.getTime())) {
queryTime = new Date(); // fallback to now
} Type guard
function isUsableDate(v: unknown): v is Date {
return v instanceof Date && Number.isFinite(v.getTime());
} Try / catch
try {
await recall(query, { queryTime });
} catch (e) {
if (e instanceof RangeError && e.message === "Invalid query time") {
await recall(query, {}); // default to now
} else throw e;
} Prevention
- Validate Dates at deserialization boundaries (JSON.parse yields strings, not Dates).
- Use parseQueryTime's string path (ISO/ YYYY-MM-DD) when the source is textual.
- Add a single sanitize step where queryTime is produced, not at every call site.
When it happens
Trigger: Passing `queryTime` as a Date built from invalid input (e.g. `new Date(NaN)` or `new Date("foo")`) to recall/decay/scoreCandidate/eventBoost options.
Common situations: Date fields round-tripped through JSON that lost their validity, arithmetic on dates producing NaN, or developer confusion between numeric timestamps (ms) and Date objects.
Related errors
- Invalid Date
- Invalid ISO datetime: ${value}
- queryTime must be null, an ISO date string, or a valid Date
- date bound must be valid
- Unsupported language '{value}'. Supported: {}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c800a22596a1126d.
Report an issue: GitHub.