clockworklabs/SpacetimeDB · error

Cannot read environment schema: HTTP

Error message

Cannot read environment schema: HTTP {}

What it means

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.

Solutions

  1. Check the printed HTTP status: 401/403 → re-run `spacetime login`; 404 → verify server version supports environment publication.
  2. Use the exact `https://` URL for the server to avoid 3xx redirects (redirects are disabled on purpose).
  3. Confirm the server is reachable and the URL is the API base, not a dashboard page.
  4. Inspect server logs to see why `/environment` rejected the request.

Example fix

// before
spacetime publish -s http://prod.example mydb  # redirect -> Cannot read environment schema: HTTP 301
// after
spacetime publish -s https://prod.example mydb
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: reach /environment with auth before the real publish
code=$(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $TOKEN" "$SERVER/environment")
[[ "$code" =~ ^2 ]] || { echo "/environment returned $code"; exit 1; }

Try / catch

// handle by status class
let e = err.to_string();
if e.contains("401") || e.contains("403") { relogin().await?; }
else if e.contains("30") || e.contains("404") { fix_server_url_or_version()?; }

Prevention

When it happens

Trigger: 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`).

Common situations: 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://`.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20). Data as JSON: /api/errors/0d0d8ebeac95fa90. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/subcommands/publish/environment.rs:117

            y_or_n(yes.publish_to_remote, "Are you sure you want to proceed?")?,
            "Publish aborted by user"
        );
    }
    let auth = get_auth_header(config, anonymous, server, !yes.skip_login).await?;
    let encoded = percent_encoding::percent_encode(
        database.as_bytes(),
        const { &percent_encoding::NON_ALPHANUMERIC.remove(b'_').remove(b'-') },
    )
    .to_string();
    let url = format!("{host}/v1/database/{encoded}");
    // Neither credentials nor publish bodies may be forwarded to redirect destinations.
    let client = reqwest::Client::builder()
        .redirect(reqwest::redirect::Policy::none())
        .build()?;
    let response = add_auth_header_opt(client.get(format!("{url}/environment")), &auth)
        .send()
        .await?;
    anyhow::ensure!(
        response.status().is_success(),
        "Cannot read environment schema: HTTP {}",
        response.status()
    );
    let metadata: EnvironmentMetadata = response.json().await.context("Invalid environment metadata")?;
    let schema = EnvironmentSchema::new(metadata.declarations)?;
    let resolved = resolve(&schema, input, |key| std::env::var_os(key))?;
    options.validate_values(&resolved.values)?;
    print!("{}", resolved.display());
    let request = PublishRequest {
        module: None,
        environment: resolved.values,
        environment_remove: options.remove.clone(),
        environment_replace: options.replace,
        expected_module_version: Some(metadata.module_version),
    };
    let response = add_auth_header_opt(client.put(url), &auth)
        .header(reqwest::header::CONTENT_TYPE, CONTENT_TYPE)

View on GitHub (pinned to eddf9f5014)