BloopAI/vibe-kanban · error

Channel already has an active session

Error message

Channel already has an active session

What it means

spawn_stdio_session spawns a local shell (or exec command) for an SSH channel, but only when the channel is in the Pending state. If the channel was already transitioned to Active by a prior shell/exec request, it is removed from the pending map and this bail fires. It guards against double session spawn per channel.

Source

Thrown at crates/embedded-ssh/src/handler.rs:63

        }
    }

    fn spawn_stdio_session(
        &mut self,
        channel_id: ChannelId,
        command: Option<&str>,
        session: &mut Session,
    ) -> Result<(), anyhow::Error> {
        tracing::debug!("Spawning stdio session (no PTY)");
        let state = self
            .channels
            .remove(&channel_id)
            .ok_or_else(|| anyhow::anyhow!("Channel not found"))?;

        let env = match state {
            ChannelState::Pending { channel: _, env } => env,
            ChannelState::Active { .. } => {
                anyhow::bail!("Channel already has an active session");
            }
        };

        let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
        let mut cmd = Command::new(shell);
        match command {
            Some(cmd_str) => {
                cmd.arg("-c");
                cmd.arg(cmd_str);
            }
            None => {
                // Non-interactive shell reading commands from stdin.
                cmd.arg("-s");
            }
        }

        cmd.stdin(Stdio::piped());
        cmd.stdout(Stdio::piped());

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Open a new SSH channel before requesting a second shell/exec session
  2. Fix client code so only one session request is made per channel
  3. Check channel state (ChannelState::Active) client-side before re-issuing the request

Example fix

// before
session.request_shell(channel_id);
session.request_shell(channel_id); // bails: Channel already has an active session
// after
session.open_channel().await?;
session.request_shell(new_channel_id).await?;
Defensive patterns

Strategy: validation

Validate before calling

if channel_state_is_active(channel_id) { return Err("session already running; open a new channel"); }

Type guard

fn is_pending(state: &ChannelState) -> bool { matches!(state, ChannelState::Pending { .. }) }

Try / catch

match spawn_stdio_session(ch).await { Err(e) if e.to_string().contains("Channel already has an active session") => open_new_channel_and_retry(), other => other? }

Prevention

When it happens

Trigger: Calling shell_request or exec_request twice on the same SSH channel; a client sending a second 'shell' or 'exec' request after a session already started on that channel.

Common situations: Misbehaving or buggy SSH clients issuing duplicate session requests; a client sending exec right after shell on the same channel; reconnect logic re-sending a request without opening a new channel.

Related errors


AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29). Data as JSON: /api/errors/96267b9ca883cc7e. Report an issue: GitHub.