clockworklabs/SpacetimeDB · error
Invalid environment read projection
Error message
Invalid environment read projection
What it means
Thrown by `render` when the single SQL statement result's schema does not match the expected projection: for `Query::List` the columns must be exactly `key` and `value`, for `Query::Get` exactly `value`, all of `AlgebraicType::String`. This validates the server returned the exact requested columns before rendering values.
Solutions
- Upgrade or downgrade the CLI to match the server version.
- Verify the environment-read SQL used matches the current server's supported syntax.
- If behind a proxy, ensure it does not rewrite the SQL response schema.
- Report/inspect the raw JSON response to see the actual column names and types.
Defensive patterns
Strategy: validation
Validate before calling
// confirm expected columns before use assert_eq!(result.schema.elements.len(), expected.len());
Type guard
fn has_expected_schema(r: &SqlStmtResult<Vec<String>>, expected: &[&str]) -> bool {
r.schema.elements.len() == expected.len()
&& r.schema.elements.iter().zip(expected)
.all(|(c, n)| c.name.as_deref() == Some(*n))
} Prevention
- Upgrade CLI and server together.
- Do not transform SQL responses in intermediaries.
- Assert schema in CI against your server version.
When it happens
Trigger: `result.schema.elements` has a different length, column names, or column types than the expected projection — e.g. the server ignored the projection, renamed columns, or returned a different type.
Common situations: Server/CLI version mismatch changing SQL result metadata; a custom server or proxy altering the schema; querying a non-standard endpoint that echoes a full-table schema.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to generate table due to validation errors
- Invalid environment read row
- schema entry ' ' must be a table or a submodule namespace…
- `table_id` must not be `TableId::SENTINEL` in
- table schema should validate for query builder codegen
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/7018c63354ab2b78.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/subcommands/env.rs:129
body.len().saturating_add(chunk.len()) <= limit,
"Environment read response exceeds limit"
);
body.extend_from_slice(&chunk);
}
render(&body, &query)
}
fn render(body: &[u8], query: &Query) -> anyhow::Result<String> {
// Validate the requested projection before rendering any response values.
let results: Vec<spacetimedb_client_api_messages::http::SqlStmtResult<Vec<String>>> =
serde_json::from_slice(body).map_err(|_| anyhow::anyhow!("Invalid environment read response"))?;
ensure!(results.len() == 1, "Invalid environment read result count");
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 {View on GitHub (pinned to eddf9f5014)