clockworklabs/SpacetimeDB · error

Invalid publish response

Error message

Invalid publish response

What it means

After a successful (2xx) publish response, the CLI deserializes the body into `PublishResult`. If the body is missing or not valid JSON matching the expected shape, `res.json()` fails and this error is thrown. A 2xx status with a non-JSON body indicates the server (or an intermediary) did not return the expected publish result.

Solutions

  1. Verify the `--server` URL points at a real Spacetimedb server, not a landing page or proxy.
  2. Check CLI/server version compatibility (`spacetime --version`) and upgrade the CLI to match the server.
  3. Inspect the raw response (curl the same endpoint with the same headers) to see what the body actually is.
  4. Retry in case of a transient intermediary failure; bypass any proxy if possible.

Example fix

// before
spacetime publish --server https://gateway.example.com mydb  // 200 with HTML body -> Invalid publish response
// after: target the SpacetimeDB API host directly
spacetime publish --server https://spacetimedb.example.com mydb
Defensive patterns

Strategy: retry

Validate before calling

// verify the endpoint speaks SpacetimeDB before publishing
curl -fsS "$SERVER/v1/database/mydb/schema" >/dev/null || echo "not a SpacetimeDB API host"

Try / catch

// retry transiently on response-shape failures
let mut attempts = 0;
loop {
    match publish().await {
        Err(e) if e.to_string().contains("Invalid publish response") && attempts < 3 => {
            attempts += 1; tokio::time::sleep(Duration::from_secs(2 * attempts)).await;
        }
        other => break other,
    }
}

Prevention

When it happens

Trigger: Server returns 200 with an empty or HTML body; an intermediary (proxy, gateway) rewrites the response; server version returns a JSON shape the CLI's `PublishResult` enum cannot deserialize.

Common situations: Publishing through a corporate proxy that mangles responses; pointing the CLI at a non-SpacetimeDB endpoint; version skew between CLI and server changing the response format.

Related errors


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

Appendix: source

Thrown at crates/cli/src/subcommands/publish.rs:779

        println!("Publishing module...");

        builder = add_auth_header_opt(builder, &auth_header);

        // Set the host type.
        builder = builder.query(&[("host_type", host_type)]);

        let (content_type, payload) =
            publication_body(&module_schema, program_bytes, environment.values, environment_options)?;
        let res = builder
            .header(reqwest::header::CONTENT_TYPE, content_type)
            .body(payload)
            .send()
            .await?;
        anyhow::ensure!(res.status().is_success(), "Publish failed with HTTP {}", res.status());
        let response: PublishResult = res
            .json()
            .await
            .map_err(|_| anyhow::anyhow!("Invalid publish response"))?;
        match response {
            PublishResult::Success {
                domain,
                database_identity,
                op,
            } => {
                let op = match op {
                    PublishOp::Created => "Created new",
                    PublishOp::Updated => "Updated",
                };
                if let Some(ref domain) = domain {
                    println!("{op} database with name: {domain}, identity: {database_identity}");
                } else {
                    println!("{op} database with identity: {database_identity}");
                }

                if is_maincloud_host(&database_host)
                    && let Some(domain) = domain.as_ref()

View on GitHub (pinned to eddf9f5014)