Hmbown/CodeWhale · error · Error

Pet tape exceeds 24 hours.

Error message

Pet tape exceeds 24 hours.

What it means

A pet tape may contain at most 216,000 rows — one bucket per PET_BIN_MS covering 24 hours. decodePetJSONL throws this error when the parsed row count exceeds that cap, preventing multi-day tapes from being replayed as if they were a single day.

Solutions

  1. Trim the tape to the most recent 216,000 rows before decoding.
  2. Fix the producer to emit exactly one row per PET_BIN_MS interval.
  3. Deduplicate or rotate the tape at the source.
  4. Only decode the trailing 24-hour window you care about.

Example fix

// before
const rows = decodePetJSONL(entireWeekText);
// after
const lines = entireWeekText.trim().split('\n').slice(-216000);
const rows = decodePetJSONL(lines.join('\n'));
Defensive patterns

Strategy: validation

Validate before calling

const lineCount = text.split('\n').filter(l => l.trim()).length;
if (lineCount > 216000) text = text.split('\n').slice(-216000).join('\n');

Type guard

const fitsIn24h = (text) => text.split('\n').filter(l => l.trim()).length <= 216000;

Try / catch

try { rows = decodePetJSONL(text); }
catch (e) { if (e.message === 'Pet tape exceeds 24 hours.') { rows = decodePetJSONL(lastDay(text)); } else throw e; }

Prevention

When it happens

Trigger: decodePetJSONL given text with more than 216,000 non-empty JSONL lines — e.g. a tape spanning multiple days, duplicated rows from double-appending, or a producer using a smaller bin duration than PET_BIN_MS (yielding more rows per day).

Common situations: Tape files accumulated across several days without rotation; a producer bug emitting sub-bin samples as separate rows; concatenated tapes from multiple devices.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

exports.PET_BIN_MS = 400;
function validatePetBucket(value) {
    (0, pet_sim_js_1.validatePetState)(value);
    const b = value;
    if (!b || typeof b !== 'object' || b.version !== 1 || !Number.isSafeInteger(b.sequence) || b.sequence < 0 || b.sequence > pet_sim_js_1.PET_MAX_SECONDS * 2.5
        || b.simTimeMs !== b.sequence * exports.PET_BIN_MS || b.durationMs !== exports.PET_BIN_MS
        || !model_js_1.CATEGORIES.includes(b.channel) || typeof b.waiting !== 'boolean'
        || !Array.isArray(b.agentIds) || b.agentIds.length > 250_000 || b.agentIds.some(id => typeof id !== 'string' || !id || id.length > 4096)
        || !Number.isSafeInteger(b.errors) || b.errors < 0 || b.errors > 250_000
        || !Array.isArray(b.onsets) || b.onsets.length !== 13 || b.onsets.some(n => !Number.isSafeInteger(n) || n < 0 || n > 250_000)
        || !Array.isArray(b.activeMs) || b.activeMs.length !== 13 || b.activeMs.some(n => !Number.isFinite(n) || n < 0 || n > 100_000_000))
        throw new Error('Invalid version 1 pet bucket.');
}
function decodePetJSONL(text) {
    if (text.length > 64 * 1024 * 1024)
        throw new Error('Pet tape exceeds 64 MiB.');
    const rows = text.split(/\r?\n/).filter(line => line.trim()).map(line => JSON.parse(line));
    if (rows.length > 216_000)
        throw new Error('Pet tape exceeds 24 hours.');
    return rows.map((row, i) => { validatePetBucket(row); if (row.sequence !== i)
        throw new Error('Non-contiguous pet tape.'); return row; });
}
/** A live file must advance before its contents count as a new observation.
 * Existing bytes, duplicate samples and a restarted sequence establish a
 * baseline; they never replay an old onset or human request. Drivers supply a
 * bounded tail and reset this cursor after suspension or a new attachment. */
class PetLiveTape {
    sequence;
    reset() { this.sequence = undefined; }
    readTail(text) {
        if (!text) {
            this.reset();
            return;
        }
        if (text.length > 262_144) {
            this.reset();
            throw new Error('Live pet input exceeds its tail limit.');

View on GitHub (pinned to 433685b202)