Hmbown/CodeWhale · error · Error

Invalid Runtime retention horizon.

Error message

Invalid Runtime retention horizon.

What it means

prune(beforeWall) computes a retention cutoff from the given wall-clock timestamp; a non-finite value (NaN, Infinity, undefined coerced) cannot define a valid horizon, so the call is rejected. This is a defensive guard ensuring retention math never silently prunes everything or nothing.

Solutions

  1. Ensure the beforeWall argument is a finite epoch-milliseconds number before calling prune.
  2. Fix the timestamp source: use Date.now() or validate parsed values with Number.isFinite.
  3. Default the argument when the clock source is unavailable.
  4. Add a Number.isFinite check at the call site.

Example fix

// before
rt.prune(Date.parse(meta.updatedAt)); // NaN if updatedAt is malformed
// after
const t = Date.parse(meta.updatedAt);
if (Number.isFinite(t)) rt.prune(t);
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isFinite(beforeWall)) throw new TypeError('prune requires a finite epoch-ms timestamp');

Type guard

const isFiniteMs = (t) => typeof t === 'number' && Number.isFinite(t);

Try / catch

try { rt.prune(t); } catch (e) { if (e.message.includes('retention horizon')) rt.prune(Date.now()); else throw e; }

Prevention

When it happens

Trigger: Calling runtime.prune(NaN), prune(Infinity), or prune(undefined) — commonly when the caller's wall-clock source (Date parse, counter) failed and produced NaN.

Common situations: Parsing a missing or malformed timestamp into a number that becomes NaN; passing a uninitialized variable intended to hold 'now'; arithmetic overflow producing Infinity.

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


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/32dc12ff618eb6ad. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/pet_watch/pet-native.js:2275

            this.bytes = total;
            this.sizes.set(event, size);
        }
        for (const key of Object.keys(event))
            if (!Object.hasOwn(safe, key))
                delete event[key];
        Object.assign(event, safe);
    }
    push(event) {
        if (this.events.length >= this.maxEvents)
            throw new Error(`Import exceeds the ${this.maxEvents.toLocaleString()} event limit.`);
        this.measure(event);
        pushEvent(this.events, event);
    }
    /** Keep unfinished lifetimes plus the recent window needed by the bucketer's
     * 12-second recurrence measure. A completion may still arrive for any open item. */
    prune(beforeWall) {
        if (!Number.isFinite(beforeWall))
            throw new Error('Invalid Runtime retention horizon.');
        if (this.origin === undefined)
            return;
        const cutoff = beforeWall - this.origin;
        let keep = 0;
        for (const event of this.events) {
            if (event.openEnded || Math.max(event.endTime, (0, model_js_1.errorOnsetOf)(event)) >= cutoff)
                this.events[keep++] = event;
            else {
                this.bytes -= this.sizes.get(event) ?? 0;
                this.sizes.delete(event);
                if (this.open.get(event.id) === event)
                    this.open.delete(event.id);
            }
        }
        this.events.length = keep;
    }
    append(records) {
        if (!records.length)

View on GitHub (pinned to 73e0f67d83)