{"record":{"id":"3904ef37be1b6266","repo":"Hmbown/CodeWhale","slug":"invalid-engine-batch","errorCode":null,"errorMessage":"Invalid Engine batch.","messagePattern":"Invalid Engine batch\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":97,"sourceCode":"        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) {\n        const events = JSON.parse(metadataJSON);\n        if (!Array.isArray(events) || events.length > 64)\n            throw new Error('Invalid Engine batch.');\n        const next = this.engine.clone();\n        for (const event of events)\n            next.observe(event, timeMs);\n        this.engine = next;\n    }\n    advanceEngine(timeMs, motion, waiting) {\n        const target = Math.floor(timeMs * 30 / 1000 + 1e-8);\n        if (!Number.isFinite(timeMs) || target < this.engineTick || target - this.engineTick > 300)\n            throw new Error('Engine pet clock jump.');\n        this.engine.confirmWaiting(timeMs, waiting);\n        const voices = [];\n        while (this.engineTick < target) {\n            if ((this.engineTick + 1) % 12 === 0)\n                this.world.acceptTelemetry(this.engine.bucket(Math.floor(this.engineTick / 12)));\n            this.world.step(1 / 30, { motion, sensitivity: 1 });\n            voices.push(...this.world.voices);\n            this.engineTick++;\n        }","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L79-L115","documentation":"The `browser` tool's `click` action requires at least one valid target: a non-empty string `selector` or a `point` object with finite numeric x and y. Providing neither (missing, wrong type, empty/blank selector, or non-finite coordinates) throws this error.","triggerScenarios":"resolveTool(\"browser\", {action:\"click\"}) with no target; selector: \"\" or \"  \"; point: {x:NaN,y:200}; point: {x:\"100\",y:200} (string coords fail Number.isFinite); selector: {css:\"#a\"} (non-string).","commonSituations":"A click args object assembled from conditionally-filled fields where neither branch ran; coordinates computed from a failed element-lookup returning NaN; selector taken from an empty DOM query result; JSON round-trip turning numbers into strings.","solutions":["Pass selector:\"css-selector\" for DOM targeting, or point:{x:Number,y:Number} for coordinate targeting.","Verify the point coordinates are finite numbers (not strings/NaN) before calling.","If the selector came from a failed lookup, re-resolve the element instead of clicking an empty selector."],"exampleFix":"// before\nresolveTool(\"browser\", { action: \"click\", selector: \"\" });\n// after\nresolveTool(\"browser\", { action: \"click\", selector: \"#submit\" });","handlingStrategy":"validation","validationCode":"const hasSelector = typeof a.selector === \"string\" && a.selector.trim();\nconst hasPoint = a.point != null && Number.isFinite(a.point.x) && Number.isFinite(a.point.y);\nif (!hasSelector && !hasPoint) {\n  throw new Error(\"click needs selector (non-empty string) or point {x:number,y:number}\");\n}","typeGuard":"const hasClickTarget = (a) =>\n  (typeof a.selector === \"string\" && a.selector.trim().length > 0) ||\n  (a.point != null && Number.isFinite(a.point.x) && Number.isFinite(a.point.y));","tryCatchPattern":null,"preventionTips":["Check point coordinates are finite numbers, not strings or NaN from a failed lookup.","Never pass empty/blank selectors from failed DOM queries — re-resolve instead.","Require exactly one of selector/point in your click call-site helper."],"tags":["argument-validation","missing-argument","browser-automation"],"backgroundTag":"missing-required-argument","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"}