{"record":{"id":"943a3a269754ee77","repo":"clockworklabs/SpacetimeDB","slug":"invalid-url-url","errorCode":null,"errorMessage":"Invalid url: {url}","messagePattern":"Invalid url: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/server.rs","lineNumber":199,"sourceCode":"\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\n    let fingerprint = if no_fingerprint {\n        None\n    } else {\n        let fingerprint = spacetime_server_fingerprint(url).await.with_context(|| {\n            format!(\n                \"Unable to retrieve fingerprint for server: {url}\nIs the server running?\nAdd a server without retrieving its fingerprint with:\n\\tspacetime server add --url {url} --no-fingerprint\",\n            )\n        })?;\n        println!(\"For server {url}, got fingerprint:\\n{fingerprint}\");\n        Some(fingerprint)\n    };\n","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/cli/src/subcommands/server.rs#L181-L217","documentation":"`spacetime server add` trims trailing `/` from the URL, then calls `host_or_url_to_host_and_protocol`, which returns `None` for the protocol when the input contains no `://` (see `contains_protocol`, util.rs:303). A `None` here means the argument did not look like a URL with a scheme, so the CLI refuses it with this error before protocol validation or fingerprint fetching happen.","triggerScenarios":"Running `spacetime server add --url myhost.example.com` (bare host, no scheme), or a mangled URL like `http//host` or `host:/https://` where the `://` delimiter is missing after trimming.","commonSituations":"Muscle-memory from tools that accept bare hostnames; copy-paste losing the scheme; a shell variable that was empty or whitespace-mangled so only part of the URL survived.","solutions":["Prefix the host with `http://` or `https://`, e.g. `--url https://myhost.example.com`","Verify the exact string being passed (quote it in the shell) and that it contains a literal `://`","For local dev use `--url http://localhost:3000` or whatever port your standalone server listens on"],"exampleFix":"# before\nspacetime server add --url testnet.spacetimedb.com --name testnet\n# after\nspacetime server add --url https://testnet.spacetimedb.com --name testnet","handlingStrategy":"validation","validationCode":"# Require a scheme before calling server add\ncase \"$1\" in *://*) ;; *) echo \"missing scheme: use https://host\"; exit 2;; esac\nspacetime server add --url \"$1\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store full URLs (scheme included) in configuration used by scripts","Quote URL arguments so shells can't split or glob them"],"tags":["spacetimedb","server-config","url-validation","cli"],"backgroundTag":"invalid-url-format","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}