{"record":{"id":"0d0d8ebeac95fa90","repo":"clockworklabs/SpacetimeDB","slug":"cannot-read-environment-schema-http","errorCode":null,"errorMessage":"Cannot read environment schema: HTTP {}","messagePattern":"Cannot read environment schema: HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/publish/environment.rs","lineNumber":117,"sourceCode":"            y_or_n(yes.publish_to_remote, \"Are you sure you want to proceed?\")?,\n            \"Publish aborted by user\"\n        );\n    }\n    let auth = get_auth_header(config, anonymous, server, !yes.skip_login).await?;\n    let encoded = percent_encoding::percent_encode(\n        database.as_bytes(),\n        const { &percent_encoding::NON_ALPHANUMERIC.remove(b'_').remove(b'-') },\n    )\n    .to_string();\n    let url = format!(\"{host}/v1/database/{encoded}\");\n    // Neither credentials nor publish bodies may be forwarded to redirect destinations.\n    let client = reqwest::Client::builder()\n        .redirect(reqwest::redirect::Policy::none())\n        .build()?;\n    let response = add_auth_header_opt(client.get(format!(\"{url}/environment\")), &auth)\n        .send()\n        .await?;\n    anyhow::ensure!(\n        response.status().is_success(),\n        \"Cannot read environment schema: HTTP {}\",\n        response.status()\n    );\n    let metadata: EnvironmentMetadata = response.json().await.context(\"Invalid environment metadata\")?;\n    let schema = EnvironmentSchema::new(metadata.declarations)?;\n    let resolved = resolve(&schema, input, |key| std::env::var_os(key))?;\n    options.validate_values(&resolved.values)?;\n    print!(\"{}\", resolved.display());\n    let request = PublishRequest {\n        module: None,\n        environment: resolved.values,\n        environment_remove: options.remove.clone(),\n        environment_replace: options.replace,\n        expected_module_version: Some(metadata.module_version),\n    };\n    let response = add_auth_header_opt(client.put(url), &auth)\n        .header(reqwest::header::CONTENT_TYPE, CONTENT_TYPE)","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/subcommands/publish/environment.rs#L99-L135","documentation":"Before publishing environment values, `publish_only` GETs `{url}/environment` to fetch the server's declared environment metadata. If the response status is not a success, `ensure!` fails with this message. The request is made with redirects disabled, so redirect statuses (3xx) also trigger this error.","triggerScenarios":"The `/environment` endpoint returns 401/403 (missing or expired auth), 404 (server doesn't support the environment API / wrong URL), or 3xx (server redirects HTTP→HTTPS or to another host, and the client has `Policy::none`).","commonSituations":"Stale login token on a remote server; pointing at an old server version without the environment feature; using an `http://` URL where the server redirects to `https://`.","solutions":["Check the printed HTTP status: 401/403 → re-run `spacetime login`; 404 → verify server version supports environment publication.","Use the exact `https://` URL for the server to avoid 3xx redirects (redirects are disabled on purpose).","Confirm the server is reachable and the URL is the API base, not a dashboard page.","Inspect server logs to see why `/environment` rejected the request."],"exampleFix":"// before\nspacetime publish -s http://prod.example mydb  # redirect -> Cannot read environment schema: HTTP 301\n// after\nspacetime publish -s https://prod.example mydb","handlingStrategy":"validation","validationCode":"// pre-flight: reach /environment with auth before the real publish\ncode=$(curl -s -o /dev/null -w '%{http_code}' -H \"Authorization: Bearer $TOKEN\" \"$SERVER/environment\")\n[[ \"$code\" =~ ^2 ]] || { echo \"/environment returned $code\"; exit 1; }","typeGuard":null,"tryCatchPattern":"// handle by status class\nlet e = err.to_string();\nif e.contains(\"401\") || e.contains(\"403\") { relogin().await?; }\nelse if e.contains(\"30\") || e.contains(\"404\") { fix_server_url_or_version()?; }","preventionTips":["Use exact https:// API base URLs — redirects are intentionally disabled.","Refresh login tokens before publishing to remote servers.","Verify the server version supports the environment API before relying on it."],"tags":["http","environment","cli","server-response"],"backgroundTag":"http-error-response","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}