{"record":{"id":"203cbdca047e544c","repo":"xai-org/grok-build","slug":"just-created","errorCode":null,"errorMessage":"just created","messagePattern":"just created","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/codegen/xai-grok-pager/src/app/mermaid_worker.rs","lineNumber":918,"sourceCode":"    }\n\n    /// Representative content columns for diagram render sizing this frame.\n    fn mermaid_content_cols(&self) -> u16 {\n        representative_content_cols(self.last_terminal_size.0)\n    }\n\n    /// Drive the lazy mermaid work for one tick: poll the worker for finished on-click renders and run each requesting action.\n    /// Returns `true` when a redraw is warranted. A no-op until a click is in flight.\n    pub fn mermaid_tick(&mut self) -> bool {\n        self.poll_mermaid_results()\n    }\n\n    /// Lazily create the render runtime (and spawn the worker) on first need.\n    fn ensure_mermaid_runtime(&mut self) -> &mut MermaidRuntime {\n        if self.mermaid.is_none() {\n            self.mermaid = Some(MermaidRuntime::new());\n        }\n        self.mermaid.as_mut().expect(\"just created\")\n    }\n\n    /// Per-session destination path for a diagram's PNG, or `None` until session identity is known (no on-disk cache before then).\n    fn mermaid_out_path(&self, key: &MermaidCacheKey) -> Option<PathBuf> {\n        // Test override: a hermetic per-test cache dir (no `GROK_HOME` mutation)\n        #[cfg(test)]\n        if let Some(path) = TEST_MERMAID_DIR.with(|d| {\n            d.borrow()\n                .as_ref()\n                .map(|tmp| tmp.path().join(key.cache_filename()))\n        }) {\n            return Some(path);\n        }\n        let dir = crate::prompt_images::session_mermaid_dir(\n            self.session.session_id.as_ref(),\n            &self.session.cwd,\n        )?;\n        Some(dir.join(key.cache_filename()))","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/app/mermaid_worker.rs#L900-L936","documentation":"`ensure_mermaid_runtime` lazily creates the `MermaidRuntime` and then unwraps `self.mermaid.as_mut().expect(\"just created\")`. The expect is an internal invariant: the Option was set two lines earlier, so this can only panic if re-entrant mutable access or a panic mid-initialization left the state inconsistent — practically it should be unreachable.","triggerScenarios":"Only reachable if `MermaidRuntime::new()` panics (leaving the field never stored) or if the borrow/invariant around `&mut self` is violated by refactoring; normal call flow (first mermaid render request via `request_mermaid_render`) cannot trigger it.","commonSituations":"A refactor that moved or removed the `self.mermaid = Some(...)` assignment; `MermaidRuntime::new()` panicking during asset/worker initialization (see error 745's thread spawn); concurrent access bugs surfaced by unsafe code changes.","solutions":["Confirm `MermaidRuntime::new()` doesn't panic (it spawns the worker — check error 745 conditions).","Inspect recent refactors of `ensure_mermaid_runtime` to ensure the Some(...) assignment still precedes the expect.","Rewrite to a single expression avoiding the intermediate expect: `self.mermaid.get_or_insert_with(MermaidRuntime::new)`.","If it fires, treat it as a logic bug — add a debug_assert/log capturing how the field was None after assignment."],"exampleFix":"// before\nif self.mermaid.is_none() {\n    self.mermaid = Some(MermaidRuntime::new());\n}\nself.mermaid.as_mut().expect(\"just created\")\n// after\nself.mermaid.get_or_insert_with(MermaidRuntime::new)","handlingStrategy":"type-guard","validationCode":"// collapse the lazy-init so no expect is needed\nlet rt = self.mermaid.get_or_insert_with(MermaidRuntime::new);","typeGuard":"fn runtime_ready(rt: &Option<MermaidRuntime>) -> bool {\n    rt.is_some()\n}","tryCatchPattern":"// not applicable: invariant panic; use get_or_insert_with to remove it\nlet rt = self.mermaid.get_or_insert_with(MermaidRuntime::new);","preventionTips":["Prefer Option::get_or_insert_with over set-then-expect lazy init","Review refactors touching this method for removed Some(...) assignment","Add a unit test exercising first-render to keep the lazy path covered"],"tags":["rust","invariant","panic","lazy-init","mermaid"],"backgroundTag":"unreachable-expect-panic","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}