clockworklabs/SpacetimeDB · error

{errno}

Error message

{errno}

What it means

Panic in the safe wrapper over the procedure_http_request syscall. Request-level failures (DNS, connect, timeout) are deliberately mapped by the host to HTTP_ERROR, which the wrapper returns as Err(BytesSource) - those do not panic. The panic fires only for the remaining errnos: WOULD_BLOCK_TRANSACTION (a transaction is currently open) and BSATN_DECODE_ERROR (the serialized spacetimedb_lib::http::Request was malformed).

Source

Thrown at crates/bindings-sys/src/lib.rs:1655

    ) -> Result<(raw::BytesSource, raw::BytesSource), raw::BytesSource> {
        let mut out = [raw::BytesSource::INVALID; 2];

        let res = unsafe {
            super::raw::procedure_http_request(
                http_request_bsatn.as_ptr(),
                http_request_bsatn.len() as u32,
                body.as_ptr(),
                body.len() as u32,
                &mut out as *mut [raw::BytesSource; 2],
            )
        };

        match super::Errno::from_code(res) {
            // Success: `out` is a `spacetimedb_lib::http::Response`.
            None => Ok((out[0], out[1])),
            // HTTP_ERROR: `out` is a `spacetimedb_lib::http::Error`.
            Some(errno) if errno == super::Errno::HTTP_ERROR => Err(out[0]),
            Some(errno) => panic!("{errno}"),
        }
    }
}

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Move outbound HTTP calls out of reducers - perform them from an HTTP-module handler context where no reducer transaction is open.
  2. Handle the Err return path (HTTP_ERROR) for real request failures instead of assuming success.
  3. Align the spacetimedb crate version with the host version and republish the module.

Example fix

// before: outbound HTTP from a reducer (transaction open -> panic)
#[spacetimedb::reducer]
fn call_api(ctx: &ReducerContext) {
    let _ = spacetimedb::http::client::request(req).unwrap(); // panics WOULD_BLOCK_TRANSACTION
}

// after: outbound HTTP in an http handler; reducers only enqueue work
#[spacetimedb::http] 
fn trigger_api() { let _ = spacetimedb::http::client::request(req); }
Defensive patterns

Strategy: validation

Try / catch

match spacetimedb::http::client::request(req) {
    Ok(resp) => { /* http::Response */ }
    Err(err_source) => { /* read http::Error from the BytesSource - real request failure */ }
}

Prevention

When it happens

Trigger: Issuing an outbound HTTP request from inside a reducer - reducers always hold an open transaction, so the host returns WOULD_BLOCK_TRANSACTION; or a Request whose BSATN encoding fails to decode because the module's spacetimedb lib version is out of sync with the host.

Common situations: Trying to validate input by calling an external API from a reducer; moving outbound calls into module HTTP handlers without checking which context they run in; crate/host version skew after an upgrade.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/fa8f8d59e3d8eb23. Report an issue: GitHub.