{"record":{"id":"cd931fb7db823aee","repo":"Hmbown/CodeWhale","slug":"native-habitat-exceeds-8-mib","errorCode":null,"errorMessage":"Native habitat exceeds 8 MiB.","messagePattern":"Native habitat exceeds 8 MiB\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":76,"sourceCode":"        this.world.acceptTelemetry(packet);\n        return true;\n    }\n    resetLiveInput() { this.liveTape.reset(); return this.resumeEngine(); }\n    recording(withCheckpoint = false) { return JSON.stringify(this.world.recording(withCheckpoint)); }\n    needsSegment() { return this.world.needsSegment; }\n    prepareSegment() { this.segment = this.world.prepareSegment(); return JSON.stringify(this.segment.recording); }\n    commitSegment() { if (!this.segment)\n        throw new Error('No pet segment was prepared.'); this.segment.commit(); this.segment = undefined; }\n    checkpoint() { return JSON.stringify(this.world.checkpoint()); }\n    recordingChunk(index, completed = false) { return this.world.recordingChunk(index, completed); }\n    restoreCheckpoint(text) {\n        if (text.length > 512 * 1024)\n            throw new Error('Pet checkpoint exceeds its size limit.');\n        this.restoreRecording(JSON.stringify({ ...this.world.recording(false), checkpoint: JSON.parse(text) }));\n    }\n    restoreRecording(text) {\n        if (text.length > 8 * 1024 * 1024)\n            throw new Error('Native habitat exceeds 8 MiB.');\n        const points = this.world.sim.p.map(p => [p.hx, p.hy]);\n        this.world = pet_world_js_1.PetWorld.fromRecording(points, JSON.parse(text));\n        this.liveTape.reset();\n        this.segment = undefined;\n        this.engineTick = Math.round(this.world.frame.timeMs * 30 / 1000);\n        this.engine = new pet_engine_js_1.PetEngineTelemetry();\n    }\n    /** Resume a live host at the first unrecorded bucket. Keep every accepted\n     * interval, but never present its last observed frame as current evidence. */\n    resumeEngine() {\n        this.world.resumeObservation();\n        this.engineTick = Math.round(this.world.frame.timeMs * 30 / 1000);\n        this.engine = new pet_engine_js_1.PetEngineTelemetry();\n        this.world.voices = [];\n        return this.world.frame.timeMs;\n    }\n    observeEngine(metadataJSON, timeMs) { this.engine.observe(JSON.parse(metadataJSON), timeMs); }\n    observeEngineBatch(metadataJSON, timeMs) {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L58-L94","documentation":"The `browser` tool's `click` action targets exactly one element: either a CSS `selector` or a screen `point` {x,y}. Supplying both a valid selector and a valid point is rejected because the library cannot know which target is intended.","triggerScenarios":"resolveTool(\"browser\", {action:\"click\", selector:\"#submit\", point:{x:100,y:200}}) — both a non-empty string selector and a point with finite x and y present.","commonSituations":"Merging args from two clicks; a model hedging by giving both coordinate and selector; replaying a recorded click that stored both the resolved point and original selector; template that always fills both fields.","solutions":["Delete either `selector` or `point` so exactly one target remains.","Prefer `selector` when you know the element; keep `point` only for canvas/coordinate-based UIs.","If both values come from state, add a call-site branch that picks one deterministically (e.g. selector wins)."],"exampleFix":"// before\nresolveTool(\"browser\", { action: \"click\", selector: \"#submit\", point: { x: 100, y: 200 } });\n// after\nresolveTool(\"browser\", { action: \"click\", selector: \"#submit\" });","handlingStrategy":"validation","validationCode":"const hasSelector = typeof selector === \"string\" && selector.trim();\nconst hasPoint = point != null && Number.isFinite(point.x) && Number.isFinite(point.y);\nif (hasSelector && hasPoint) {\n  delete args.point; // pick one target deterministically\n}","typeGuard":"const clickTargetOk = (a) => {\n  const s = typeof a.selector === \"string\" && a.selector.trim();\n  const p = a.point != null && Number.isFinite(a.point.x) && Number.isFinite(a.point.y);\n  return (s || p) && !(s && p);\n};","tryCatchPattern":null,"preventionTips":["Enforce one-target-per-click in your args builder: prefer selector, fall back to point.","Don't merge click args from multiple sources without dropping the losing target field.","Store recorded clicks as either selector or point, not both."],"tags":["argument-validation","mutually-exclusive","browser-automation"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}