Hmbown/CodeWhale · error

session should exist after touch

Error message

session should exist after touch

What it means

next_turn calls touch_session(namespace) immediately before fetching the session, and touch_session guarantees insertion via entry().or_default(). This expect therefore only fires if the session map was concurrently mutated or the insert logic regressed — an internal invariant break in WebRunSessionStore, not a user-input problem.

Source

Thrown at crates/tui/src/tools/web_run.rs:141

            && let Some(oldest_namespace) = self
                .sessions
                .iter()
                .min_by_key(|(_, session)| session.last_access)
                .map(|(existing_namespace, _)| existing_namespace.clone())
        {
            self.remove_session(&oldest_namespace);
        }

        let session = self.sessions.entry(namespace.to_string()).or_default();
        session.last_access = Instant::now();
    }

    fn next_turn(&mut self, namespace: &str) -> u64 {
        self.touch_session(namespace);
        let session = self
            .sessions
            .get_mut(namespace)
            .expect("session should exist after touch");
        let current = session.next_turn;
        session.next_turn = session.next_turn.saturating_add(1);
        current
    }

    fn store_page(&mut self, namespace: &str, ref_id: &str, page: WebPage) {
        self.touch_session(namespace);
        let mut evicted_refs = Vec::new();
        {
            let session = self
                .sessions
                .get_mut(namespace)
                .expect("session should exist after touch");
            if let Some(existing_idx) = session.refs.iter().position(|existing| existing == ref_id)
            {
                session.refs.remove(existing_idx);
            }
            session.refs.push_back(ref_id.to_string());

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Keep touch_session and the sessions.get call adjacent so no code can remove the entry in between
  2. Replace the expect with a defensive or_default() insert if future changes interleave eviction logic
  3. Add a unit test that next_turn after touch_session always finds the namespace
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at crates/tui/src/tools/web_run.rs:141 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/e692be1527b694fd. Report an issue: GitHub.