Hmbown/CodeWhale · error · Error

Runtime observation exceeds its retained input limit.

Error message

Runtime observation exceeds its retained input limit.

What it means

Thrown by the Runtime retention tracker's measure() when adding/updating an observation would push the total retained JSON byte size past maxBytes. The library bounds how much raw runtime input it keeps in memory; an event that does not fit (after projection) aborts the operation. It is a capacity guard on retained input, distinct from the event-count limit.

Solutions

  1. Increase the maxBytes retention limit configured for the Runtime tracker.
  2. Trim oversized event attributes/payloads before pushing (project or drop large fields).
  3. Enable pruning (prune(beforeWall)) to free budget before pushing more events.
  4. Check which single event is oversized; a pathological attribute is usually the cause.

Example fix

// before
runtime.push(event); // throws if over maxBytes
// after
const size = new TextEncoder().encode(JSON.stringify(event)).length;
if (size > runtime.maxBytes) {
  event.attributes = { ...event.attributes, payload: '[omitted]' };
}
runtime.push(event);
Defensive patterns

Strategy: validation

Validate before calling

const size = new TextEncoder().encode(JSON.stringify(event)).length;
if (size > runtime.maxBytes) {
  event.attributes = { ...event.attributes, payload: '[omitted: too large]' };
}

Type guard

function fitsRetainedBudget(event, runtime) {
  const size = new TextEncoder().encode(JSON.stringify(event)).length;
  return size <= runtime.maxBytes;
}

Try / catch

try {
  runtime.push(event);
} catch (e) {
  if (String(e.message).includes('retained input limit')) {
    console.error('Event exceeds retention budget; trim attributes or raise maxBytes.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling push() (or otherwise measuring an event) on the Runtime retention object when bytes - existingSize(event) + newEventSize > maxBytes, i.e. the serialized event would exceed the configured byte budget at pet/ios/Resources/pet-native.js:2256. Also triggered by updates that grow an already-tracked event beyond remaining budget.

Common situations: Importing a runtime file with a very large maxBytes too small for one huge event; a single event whose attributes ballooned (e.g. a captured error or huge payload); lowering maxBytes below current usage then pushing more events.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/b65bc64642a928f9. Report an issue: GitHub.

Appendix: source

Thrown at pet/ios/Resources/pet-native.js:2256

    origin;
    model;
    threadId;
    threadName;
    constructor(filename = 'Codewhale runtime', maxEvents = 250_000, project = event => event, maxBytes = Infinity) {
        this.filename = filename;
        this.maxEvents = maxEvents;
        this.project = project;
        this.maxBytes = maxBytes;
    }
    get retainedEvents() { return this.events.length; }
    get retainedBytes() { return this.bytes; }
    measure(event, proposed = event) {
        const safe = this.project(proposed);
        if (this.maxBytes !== Infinity) {
            const size = new TextEncoder().encode(JSON.stringify(safe)).length;
            const total = this.bytes - (this.sizes.get(event) ?? 0) + size;
            if (total > this.maxBytes)
                throw new Error('Runtime observation exceeds its retained input limit.');
            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))

View on GitHub (pinned to 433685b202)