Hmbown/CodeWhale · error · anyhow::Error

Codewhale web is loopback-only and must bind to 127.0.0.1

Error message

Codewhale web is loopback-only and must bind to 127.0.0.1

What it means

The `serve` command with `--web` refuses any bind host other than 127.0.0.1 because the web UI is loopback-only. resolve_serve_bind_host computes the bind address; if args.web is set and the host is not 127.0.0.1, the command bails before starting the HTTP server. This prevents exposing the web interface (and its access to the runtime API) to other network interfaces.

Solutions

  1. Bind to the loopback interface: omit --host or pass --host 127.0.0.1.
  2. If remote access is needed, put a reverse proxy (ssh -L tunnel, nginx with auth) in front and keep the server on 127.0.0.1.
  3. Drop --web if you only need the HTTP API bound to a non-loopback address, after confirming that is intended.
  4. Check whether --mobile is implicitly altering the resolved host; set an explicit --host 127.0.0.1.

Example fix

// before
codewhale serve --web --host 0.0.0.0
// after
codewhale serve --web --host 127.0.0.1   # or forward a port: ssh -L 8080:127.0.0.1:8080 host
Defensive patterns

Strategy: validation

Validate before calling

// shell
if [ "$HOST" != "127.0.0.1" ] && [[ $ARGS == *"--web"* ]]; then echo 'web is loopback-only'; exit 1; fi

Prevention

When it happens

Trigger: Running `codewhale serve --web --host 0.0.0.0` (or any non-loopback host, or --mobile combined with a host that resolves non-loopback).

Common situations: Trying to expose the Codewhale web UI on a LAN address, running in a container and binding 0.0.0.0, or using --mobile which changes the default host resolution.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/b911bb488cb8aa90. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/lib.rs:2580

                if args.mcp {
                    mcp_server::run_mcp_server(workspace).await
                } else if http_selected {
                    let (mut config, config_profile) =
                        load_config_from_cli_with_effective_profile(&cli)?;
                    initialize_cloud_facts(&config);
                    let explicit_route_override =
                        crate::config::explicit_launch_provider_override().is_some()
                            || crate::config::explicit_launch_model_override().is_some();
                    apply_selected_fleet_operator_for_launch(
                        &mut config,
                        &workspace,
                        explicit_route_override,
                        false,
                    )?;
                    let cors_origins = resolve_cors_origins(&config, &args.cors_origin);
                    let bind_host = resolve_serve_bind_host(args.mobile, args.host);
                    if args.web && bind_host.host != "127.0.0.1" {
                        bail!("Codewhale web is loopback-only and must bind to 127.0.0.1");
                    }
                    runtime_api::run_http_server(
                        config,
                        workspace,
                        std::sync::Arc::clone(&plugin_discovery),
                        runtime_api::RuntimeApiOptions {
                            host: bind_host.host,
                            port: args.port,
                            workers: args.workers.clamp(1, 8),
                            cors_origins,
                            auth_token: args.auth_token,
                            insecure_no_auth: args.insecure_no_auth,
                            mobile: args.mobile,
                            web: args.web,
                            show_qr: args.qr,
                            config_path: cli.config.clone(),
                            config_profile,
                        },

View on GitHub (pinned to 73e0f67d83)