clockworklabs/SpacetimeDB · error

Environment read value exceeds limit

Error message

Environment read value exceeds limit

What it means

Thrown by `render` when an individual environment variable value in the response is longer than `MAX_ENV_VALUE_BYTES`. The CLI enforces the same per-value size cap the server applies on writes, so a value over the limit indicates a policy violation or protocol inconsistency.

Solutions

  1. Identify the offending key and shorten its value, then `spacetime env set KEY <shorter-value>`.
  2. Split large data across multiple variables or store it in the database instead of env vars.
  3. Upgrade the server so writes enforce the same MAX_ENV_VALUE_BYTES cap.

Example fix

// before
spacetime env set CERT $(cat huge-cert.pem)   # value too large
// after
split -b 4000 huge-cert.pem part_  # store parts, or reference cert by path
Defensive patterns

Strategy: validation

Validate before calling

// check value size before `spacetime env set`
if value.len() > spacetimedb_lib::environment::MAX_ENV_VALUE_BYTES {
    return Err("env value too large");
}

Prevention

When it happens

Trigger: `row.last().unwrap().len() > MAX_ENV_VALUE_BYTES` — a stored value exceeds the byte cap, e.g. it was written by an older version before the cap existed, or the value's byte length differs from its character length under the server's counting.

Common situations: Very long values (certificates, JSON blobs) stored via older tooling; multi-byte UTF-8 making byte length exceed expectations; server with more permissive limits than the CLI.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at crates/cli/src/subcommands/env.rs:142

    let result = &results[0];
    let expected: &[&str] = match query {
        Query::List => &["key", "value"],
        Query::Get(_) => &["value"],
    };
    ensure!(
        result.schema.elements.len() == expected.len()
            && result.schema.elements.iter().zip(expected).all(|(column, name)| {
                column.name.as_deref() == Some(*name) && column.algebraic_type == spacetimedb_lib::AlgebraicType::String
            }),
        "Invalid environment read projection"
    );
    ensure!(result.rows.len() <= MAX_ENV_VARS, "Environment key count exceeds limit");
    for row in &result.rows {
        ensure!(row.len() == expected.len(), "Invalid environment read row");
        if matches!(query, Query::List) {
            validate_key(&row[0]).context("Invalid environment key in response")?;
        }
        ensure!(
            row.last().unwrap().len() <= MAX_ENV_VALUE_BYTES,
            "Environment read value exceeds limit"
        );
    }
    match query {
        Query::List => {
            let mut rows: Vec<_> = result.rows.iter().collect();
            rows.sort_unstable_by(|a, b| a[0].cmp(&b[0]));
            let rows = rows.into_iter().map(|row| {
                Ok::<_, std::convert::Infallible>(spacetimedb_lib::sats::product![row[0].as_str(), row[1].as_str()])
            });
            let table = sql::build_table(
                spacetimedb_lib::sats::satn::PsqlClient::SpacetimeDB,
                &result.schema,
                rows,
            )?;
            Ok(format!("{table}\n"))
        }

View on GitHub (pinned to eddf9f5014)