{"record":{"id":"b0b3f32e6f2952d0","repo":"BoundaryML/baml","slug":"wasm-history-boundary-was-not-begun","errorCode":null,"errorMessage":"WASM history boundary {} was not begun","messagePattern":"WASM history boundary (.+?) was not begun","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bridge_wasm/src/runs.rs","lineNumber":114,"sourceCode":"        value_writer.append_run_started(&RunStartedRecord {\n            request: start.request.clone(),\n            created_at_ms: start.created_at_ms,\n            time_anchor: start.time_anchor,\n        })?;\n        self.boundaries\n            .insert(start.boundary_id, WasmHistoryBoundary { value_writer });\n        Ok(())\n    }\n\n    fn append_log_body(\n        &mut self,\n        boundary_id: BoundaryId,\n        event: LogEventRecord,\n        codec: ValueCodec,\n        body: Vec<u8>,\n    ) -> io::Result<ValueWriteOutcome> {\n        let boundary = self.boundaries.get_mut(&boundary_id).ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\n                    \"WASM history boundary {} was not begun\",\n                    boundary_id.to_wire_string()\n                ),\n            )\n        })?;\n        boundary.value_writer.append_log_body(codec, body, event)\n    }\n\n    fn append_capture_loss(\n        &mut self,\n        boundary_id: BoundaryId,\n        record: &CaptureLossRecord,\n    ) -> io::Result<()> {\n        let boundary = self.boundaries.get_mut(&boundary_id).ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bridge_wasm/src/runs.rs#L96-L132","documentation":"append_log_body in the WASM runs store requires a history boundary that was previously begun via begin(). The call looks up the BoundaryId in the boundaries map and, when absent, returns an io::Error of kind NotFound saying the boundary 'was not begun'. It means the caller is appending a log body to a run whose lifecycle was never started (or already finished/removed).","triggerScenarios":"Calling append_log_body with a BoundaryId that was never created, that was already completed, or from a stale reference after the boundary map dropped it.","commonSituations":"Happens in WASM test harnesses and replay paths (e.g. warm_history_replays_log_payload_and_body_without_live_runstore) when log bodies are appended after the run was torn down, or when boundary IDs are recreated/reused across page reloads.","solutions":["Ensure begin() is called for the boundary before any append_log_body call","Verify the BoundaryId is the one returned by begin(), not reconstructed from wire bytes of a closed run","Check ordering in your JS glue code so bodies are appended before the run is finished/dropped","Handle the io NotFound error in the JS caller and re-begin the boundary if replaying history"],"exampleFix":"// before\nruns.append_log_body(boundaryId, event, codec, body);\n// after\nif (!runs.hasBoundary(boundaryId)) boundaryId = runs.begin(meta);\nruns.append_log_body(boundaryId, event, codec, body);","handlingStrategy":"validation","validationCode":"function canAppendBody(runs, boundaryId) {\n  return typeof runs.hasBoundary === 'function' && runs.hasBoundary(boundaryId);\n}","typeGuard":null,"tryCatchPattern":"try {\n  runs.append_log_body(boundaryId, event, codec, body);\n} catch (e) {\n  if (String(e.message).includes('was not begun')) {\n    boundaryId = runs.begin(meta); // re-begin and retry once\n    runs.append_log_body(boundaryId, event, codec, body);\n  } else throw e;\n}","preventionTips":["Always begin() a boundary before appending any records","Keep boundary IDs from begin() return values, never reconstruct them","Append bodies before finishing/closing the run","Track boundary lifecycle centrally in glue code"],"tags":["wasm","io","lifecycle"],"backgroundTag":"record-not-found","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}