Hmbown/CodeWhale · error · Error
Pet replay exceeds 24 hours; select a shorter trace.
Error message
Pet replay exceeds 24 hours; select a shorter trace.
What it means
compilePetTelemetry() computes the number of replay bins (count) from durationMs and the last error onset and rejects replays that would exceed roughly 24 hours (more than 216,000 bins of PET_BIN_MS, or beyond PET_MAX_SECONDS * 2.5 counting from firstSequence). The pet audio simulation is bounded, so very long traces cannot be compiled.
Solutions
- Select a shorter trace (as the message says) or trim the input to a bounded time window before compiling.
- Verify originMs is passed and equals the trace start so durations are relative, not epoch-scale.
- Check errorOnsetOf values are relative offsets; normalize absolute timestamps before compiling.
- If long replays are legitimately needed, raise the limit in pet_sim (PET_MAX_SECONDS) consciously — don't patch the caller.
Example fix
// before compilePetTelemetry(events, sessionEnd - 0, 0); // durationMs is epoch-scale // after const originMs = events[0].startTime; compilePetTelemetry(events, sessionEnd - originMs, 0, originMs);
Defensive patterns
Strategy: validation
Validate before calling
const MAX_BINS = 216_000;
const originMs = events[0]?.startTime ?? 0;
const dur = Math.max(0, durationMs - originMs);
if (Math.ceil(dur / PET_BIN_MS) > MAX_BINS) {
throw new UserFacingError('Trace too long for pet replay');
} Try / catch
try {
return compilePetTelemetry(events, durationMs, first, originMs);
} catch (e) {
if (e.message.includes('exceeds 24 hours')) {
return compilePetTelemetry(trimToWindow(events, MAX_DURATION_MS), Math.min(durationMs, MAX_DURATION_MS), first, originMs);
}
throw e;
} Prevention
- Always pass a correct originMs so durations are relative, not epoch-scale
- Verify error onsets are relative offsets, not absolute timestamps
- Trim or chunk long traces to a bounded window before compiling
When it happens
Trigger: Compiling a trace whose duration (after subtracting originMs) exceeds the ~24h limit; a trace with a huge error-onset timestamp (e.g. an epoch-ms value not normalized) inflating lastOnset and thus count; forgetting to pass originMs so absolute timestamps are treated as durations.
Common situations: Selecting an overnight/long-running session trace; a bug where errorOnsetOf returns an absolute epoch time instead of a relative offset; originMs omitted or 0 while events carry epoch-millisecond timestamps, making durationMs appear enormous.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- bundle exceeds the file limit
- Complete local diff requires
- duration resolved to zero seconds
- evidence metadata exceeds limit
- exceeded the -item catalogue limit
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/4bfeef0946581d1b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:1206
throw new Error('Select one trace for the pet.');
const parents = new Set([...unique.values()].filter(e => e.parentId).map(e => e.parentId));
const events = [...unique.values()].filter(e => !isContainer(e)
&& !(e.category === 'orchestration' && parents.has(e.id)))
.map(e => ({ ...e, startTime: e.startTime - originMs, endTime: (e.openEnded ? e.startTime : e.endTime) - originMs,
attributes: e.attributes['whalesong.error_onset_ms'] === undefined ? e.attributes
: { ...e.attributes, 'whalesong.error_onset_ms': (0, model_js_1.errorOnsetOf)(e) - originMs } }))
.sort((a, b) => a.startTime - b.startTime || order(a.id, b.id));
let lastOnset = 0;
for (const e of events) {
durationMs = Math.max(durationMs, e.endTime);
lastOnset = Math.max(lastOnset, e.startTime);
}
const failures = events.filter(e => e.category === 'error' || e.status === 'error').map(model_js_1.errorOnsetOf).sort((a, b) => a - b);
if (failures.length)
lastOnset = Math.max(lastOnset, failures[failures.length - 1]);
const count = Math.max(1, Math.ceil(durationMs / exports.PET_BIN_MS), Math.floor(lastOnset / exports.PET_BIN_MS) + 1);
if (count - firstSequence > 216_000 || count > pet_sim_js_1.PET_MAX_SECONDS * 2.5)
throw new Error('Pet replay exceeds 24 hours; select a shorter trace.');
const index = new signal_js_1.IntervalIndex(events), result = [];
const recent = [], names = new Map();
let next = 0, expired = 0, nextFailure = 0;
for (let sequence = firstSequence; sequence < count; sequence++) {
const start = sequence * exports.PET_BIN_MS, end = start + exports.PET_BIN_MS;
// A trailing window only: appending future events cannot rewrite earlier bins.
while (next < events.length && events[next].startTime < end) {
const e = events[next++];
// A liveness pulse continues an operation; it is not a repeated tool call.
if (e.attributes['whalesong.continuation'] === true)
continue;
recent.push(e);
names.set(e.name, (names.get(e.name) ?? 0) + 1);
}
while (expired < recent.length && recent[expired].startTime < end - 12_000) {
const name = recent[expired++].name, n = names.get(name) - 1;
if (n)
names.set(name, n);View on GitHub (pinned to 73e0f67d83)