Hmbown/CodeWhale · error

--bridge is required in --non-interactive mode.

Error message

--bridge is required in --non-interactive mode. {bridge_choices}

What it means

Remote setup (`resolve_bridge`) requires a chat bridge. With `--non-interactive` set and no `--bridge` slug given, the interactive picker cannot run, so the function bails and appends the list of valid bridge choices. This prevents headless runs from blocking on stdin.

Solutions

  1. Add `--bridge <slug>` with a valid bridge slug from the registry.
  2. Drop `--non-interactive` to answer the 'Chat bridge' prompt interactively.
  3. Use the bridge choices listed in the error message.

Example fix

// before
codewhale remote-setup --non-interactive --cloud azure
// after
codewhale remote-setup --non-interactive --cloud azure --bridge slack
Defensive patterns

Strategy: validation

Validate before calling

if (args.nonInteractive && !args.bridge) throw new Error(`--bridge is required in --non-interactive mode`);

Try / catch

try { runRemoteSetup(args) } catch (e) { if (String(e).includes('--bridge is required')) process.exitCode = 2; else throw e; }

Prevention

When it happens

Trigger: Running remote setup with `--non-interactive` while `--bridge <slug>` is missing; also surfaced through `unknown_flags_fail_with_choices` when flag resolution delegates to the non-interactive path.

Common situations: Automation scripts that specify the cloud but forget the bridge; containerized setups with no TTY where the prompt cannot be answered.

Understand the failure class

Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/5a2252030fe989bd. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/remote_setup/mod.rs:170

        );
    }
    let idx = prompt_choice(
        "Cloud target",
        &CLOUD_TARGETS
            .iter()
            .map(|c| format!("{} ({})", c.display, c.slug))
            .collect::<Vec<_>>(),
    )?;
    Ok(&CLOUD_TARGETS[idx])
}

fn resolve_bridge(args: &RemoteSetupArgs) -> Result<&'static BridgeSpec> {
    if let Some(slug) = &args.bridge {
        return registry::bridge_by_slug(slug)
            .ok_or_else(|| anyhow::anyhow!("unknown bridge '{slug}'. {}", bridge_choices()));
    }
    if args.non_interactive {
        bail!(
            "--bridge is required in --non-interactive mode. {}",
            bridge_choices()
        );
    }
    let idx = prompt_choice(
        "Chat bridge",
        &BRIDGES
            .iter()
            .map(|b| format!("{} ({})", b.display, b.slug))
            .collect::<Vec<_>>(),
    )?;
    Ok(&BRIDGES[idx])
}

fn resolve_provider(args: &RemoteSetupArgs) -> Result<ProviderInfo> {
    if let Some(slug) = &args.provider {
        return ProviderInfo::from_slug(slug).ok_or_else(|| {
            anyhow::anyhow!(

View on GitHub (pinned to 433685b202)