{"record":{"id":"e6c8fcaa02753f77","repo":"clockworklabs/SpacetimeDB","slug":"invalid-protocol-protocol","errorCode":null,"errorMessage":"Invalid protocol: {protocol}","messagePattern":"Invalid protocol: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/server.rs","lineNumber":184,"sourceCode":"    let mut table = Table::new(&rows);\n    table\n        .with(Style::empty())\n        .with(Modify::new(Columns::first()).with(Alignment::right()));\n    println!(\"{table}\");\n\n    Ok(())\n}\n\npub async fn exec_set_default(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::Error> {\n    let server = args.get_one::<String>(\"server\").unwrap();\n    config.set_default_server(server)?;\n    config.save();\n    Ok(())\n}\n\nfn valid_protocol_or_error(protocol: &str) -> anyhow::Result<()> {\n    if !VALID_PROTOCOLS.contains(&protocol) {\n        Err(anyhow::anyhow!(\"Invalid protocol: {protocol}\"))\n    } else {\n        Ok(())\n    }\n}\n\npub async fn exec_add(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::Error> {\n    // Trim trailing `/`s because otherwise we end up with a double `//` in some later codepaths.\n    // See https://github.com/clockworklabs/SpacetimeDB/issues/1551.\n    let url = args.get_one::<String>(\"url\").unwrap().trim_end_matches('/');\n    let nickname = args.get_one::<String>(\"name\");\n    let default = *args.get_one::<bool>(\"default\").unwrap();\n    let no_fingerprint = *args.get_one::<bool>(\"no-fingerprint\").unwrap();\n\n    let (host, protocol) = host_or_url_to_host_and_protocol(url);\n    let protocol = protocol.ok_or_else(|| anyhow::anyhow!(\"Invalid url: {url}\"))?;\n\n    valid_protocol_or_error(protocol)?;\n","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/cli/src/subcommands/server.rs#L166-L202","documentation":"`valid_protocol_or_error` rejects any protocol string not in `VALID_PROTOCOLS`, which is exactly `[\"http\", \"https\"]` (crates/cli/src/util.rs:211). It is called from `spacetime server add` and `server edit` after the scheme is split off the URL. Note the sibling helper `host_or_url_to_host_and_protocol` only yields `Some(protocol)` for valid schemes, so in practice this guard is defensive; some malformed-scheme inputs can even panic earlier in that helper's `unwrap()`.","triggerScenarios":"Passing a URL whose scheme is neither http nor https — e.g. `spacetime server add --url ws://host` or `ftp://host` — to server add/edit code paths that reach this check.","commonSituations":"Copying a websocket URL from client connection strings and using it as a server URL; typos like `htps://`; assuming any scheme is accepted because the flag is named `--url`.","solutions":["Use an `http://` or `https://` URL for the server","Omit the scheme entirely and pass a bare host so the default protocol applies","Double-check the pasted URL for typos in the scheme portion"],"exampleFix":"# before\nspacetime server add --url ws://testnet.spacetimedb.com --name testnet\n# after\nspacetime server add --url https://testnet.spacetimedb.com --name testnet","handlingStrategy":"validation","validationCode":"# Accept only http/https URLs in wrappers around `server add`\ncase \"$1\" in http://*|https://*) ;; *) echo \"url must start with http:// or https://\"; exit 2;; esac","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never feed ws://wss:// client URLs into `--url`; derive the http(s) base instead","Centralize server-URL constants in one script so typos surface once"],"tags":["spacetimedb","server-config","url-validation","protocol"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}