Hmbown/CodeWhale · error · Error
Invalid failure observation time.
Error message
Invalid failure observation time.
What it means
`errorOnsetOf(e)` resolves the failure observation timestamp from the `whalesong.error_onset_ms` attribute, falling back to `e.startTime`. It throws when the attribute is present but not a finite number, or when it is earlier than the error's start time — the library treats an onset before the error began as corrupt observation data.
Solutions
- Fix the event producer so `whalesong.error_onset_ms` is a finite number of milliseconds that is >= `e.startTime`.
- Ensure units are consistent — convert seconds to ms (`seconds * 1000`) before attaching the attribute.
- If the onset is unreliable, omit the attribute entirely so the function falls back to `e.startTime` instead of throwing.
Example fix
// before e.attributes['whalesong.error_onset_ms'] = onsetSeconds; // wrong unit // after const onsetMs = Math.max(e.startTime, onsetSeconds * 1000); // ms, >= startTime e.attributes['whalesong.error_onset_ms'] = onsetMs;
Defensive patterns
Strategy: validation
Validate before calling
function isValidOnset(e) { const t = e.attributes?.['whalesong.error_onset_ms']; return t === undefined || (typeof t === 'number' && Number.isFinite(t) && t >= e.startTime); } Type guard
function hasValidOnsetAttr(e) { const t = e.attributes['whalesong.error_onset_ms']; return t === undefined || (typeof t === 'number' && Number.isFinite(t) && t >= e.startTime); } Try / catch
try { onset = errorOnsetOf(e); } catch (err) { onset = e.startTime; /* fall back, log producer bug */ } Prevention
- Standardize onset units to milliseconds at the producer boundary.
- Clamp onset to >= startTime when stamping the attribute.
- Omit the attribute rather than writing a dubious value, so the built-in startTime fallback applies.
When it happens
Trigger: Feeding error/telemetry events into the signal-view pipeline where an event carries `whalesong.error_onset_ms` that is a string, NaN, Infinity, or a value smaller than `e.startTime` (e.g. onset set in a different unit, or stamped before the error actually started).
Common situations: Producers mixing milliseconds and seconds when writing `error_onset_ms`; replaying old recordings with clock skew; test fixtures hand-writing onset attributes below startTime; JSON round-trips turning the number into a string.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid pet state.
- Archive the legacy recording before accepting more…
- Choose an appearance file smaller than 4 KiB.
- invalid_container
- Invalid Engine pet clock.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/954c3da5ce06781a.
Report an issue: GitHub.
Appendix: source
Thrown at pet/ios/Resources/pet-native.js:625
if (f.query) {
const q = f.query.toLowerCase();
// Search is deliberately content-aware but runs only over locally retained fields.
if (![e.name, e.id, e.agentId, e.model, e.tool, e.provider, e.category,
JSON.stringify(e.attributes), JSON.stringify(e.payload), JSON.stringify(e.raw)].filter(Boolean).join(' ').toLowerCase().includes(q))
return false;
}
return true;
}
const durationOf = (e) => Math.max(0, e.endTime - e.startTime);
exports.durationOf = durationOf;
/** An explicit failure receipt can arrive after a span began or ended. Keep
* its timestamp distinct from the operation onset in every signal view. */
function errorOnsetOf(e) {
const time = e.attributes['whalesong.error_onset_ms'];
if (time === undefined)
return e.startTime;
if (typeof time !== 'number' || !Number.isFinite(time) || time < e.startTime)
throw new Error('Invalid failure observation time.');
return time;
}
function stableHash(text, seed = 2166136261) {
let h = seed;
for (let i = 0; i < text.length; i++) {
h ^= text.charCodeAt(i);
h = Math.imul(h, 16777619);
}
return h >>> 0;
}
function quantile(a, q) {
if (!a.length)
return 0;
const s = [...a].sort((a, b) => a - b), x = Math.min(1, Math.max(0, q)) * (s.length - 1);
return s[Math.floor(x)] + (s[Math.ceil(x)] - s[Math.floor(x)]) * (x % 1);
}
function clamp(x, lo, hi) { return Math.max(lo, Math.min(hi, x)); }
function formatTime(ms, precise = false) {View on GitHub (pinned to 433685b202)