{"record":{"id":"67af95fb899c0457","repo":"Hmbown/CodeWhale","slug":"offline-queue-cannot-be-parked-without-a-session-id","errorCode":null,"errorMessage":"Offline queue cannot be parked without a session id","messagePattern":"Offline queue cannot be parked without a session id","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_manager.rs","lineNumber":2279,"sourceCode":"        }))\n    }\n\n    /// Park this session's offline queue (queued + draft messages).\n    ///\n    /// Queues are keyed per session (`checkpoints/<session_id>.offline_queue.json`)\n    /// for exactly the reason checkpoints are: concurrent Codewhale instances\n    /// must never overwrite — or delete — each other's unsent user text.\n    ///\n    /// A queue with no session id has no owner to restore it to, so parking is\n    /// refused rather than written to a shared file where the next boot would\n    /// destroy it.\n    pub fn save_offline_queue_state(\n        &self,\n        state: &OfflineQueueState,\n        session_id: Option<&str>,\n    ) -> std::io::Result<PathBuf> {\n        let session_id = session_id.ok_or_else(|| {\n            std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"Offline queue cannot be parked without a session id\",\n            )\n        })?;\n        let path = self.validated_offline_queue_path(session_id)?;\n        fs::create_dir_all(self.checkpoints_dir())?;\n        let mut owned = state.clone();\n        // The stamp is redundant with the file name; it stays because the UI's\n        // restore path still compares it against the live session id.\n        owned.session_id = Some(self.validated_session_id(session_id)?.to_string());\n        let content = serde_json::to_string_pretty(&owned)\n            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;\n        write_atomic(&path, content.as_bytes())?;\n        Ok(path)\n    }\n\n    /// Load one session's parked offline queue if present.\n    pub fn load_offline_queue_state(","sourceCodeStart":2261,"sourceCodeEnd":2297,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/session_manager.rs#L2261-L2297","documentation":"save_offline_queue_state persists the offline queue to a per-session path, so a session id is mandatory. Passing None makes the target path undefined; the API returns InvalidInput with \"Offline queue cannot be parked without a session id\" instead of guessing a global location.","triggerScenarios":"Calling save_offline_queue_state(&state, None) — typically from a code path that parks queued input before a session id was assigned or after it was cleared.","commonSituations":"Parking the offline queue during early startup before session creation; a shutdown path that lost track of the active session id; a refactor that made session_id optional at the call site.","solutions":["Pass the active session's id (Some(session_id)) to save_offline_queue_state","Fix the calling code to create/resolve the session before parking the offline queue","If queue state truly has no session yet, defer parking until a session id exists, or buffer it in memory"],"exampleFix":"// before\nmanager.save_offline_queue_state(&state, None)?;\n// after\nlet session_id = session.id().to_string();\nmanager.save_offline_queue_state(&state, Some(&session_id))?;","handlingStrategy":"validation","validationCode":"if session_id.is_none() {\n    return Err(\"cannot park the offline queue before a session exists\".into());\n}\nmanager.save_offline_queue_state(&state, session_id)?;","typeGuard":null,"tryCatchPattern":"match session_id {\n    Some(id) => manager.save_offline_queue_state(&state, Some(id))?,\n    None => eprintln!(\"deferring offline-queue park until a session id is assigned\"),\n}","preventionTips":["Create the session before any code path parks the offline queue","Thread session_id as non-optional wherever the queue is persisted","Add an assertion/logging when a shutdown path loses the active session id"],"tags":["offline-queue","session","argument"],"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"}