clockworklabs/SpacetimeDB · error
Environment values can only be changed by publishing
Error message
Environment values can only be changed by publishing
What it means
The `spacetime env` CLI subcommand only supports read-only operations (`list` and `get`). Any other subcommand (e.g. `set`, `unset`) reaches the catch-all arm and is rejected, because environment values are mutated exclusively through the publish flow.
Solutions
- Use `spacetime publish` (with the desired environment values in the config) to change environment values instead of `spacetime env set`.
- Check `spacetime env --help` and use only `list` or `get` to read values.
- Fix typos in the subcommand verb.
Example fix
// before spacetime env set MY_KEY myvalue // after spacetime publish --project-path . # with MY_KEY set in the environment config
Defensive patterns
Strategy: validation
Validate before calling
if !matches!(verb.as_str(), "list" | "get") { eprintln!("env values are read-only via `spacetime env`; use `spacetime publish` to change them"); std::process::exit(2); } Type guard
fn is_readonly_env_query(verb: &str) -> bool { matches!(verb, "list" | "get") } Prevention
- Only use `spacetime env list` / `spacetime env get KEY`; mutate env through publish.
- Run `spacetime env --help` to confirm supported verbs before scripting.
- Wrap env mutation in the publish pipeline, not ad-hoc commands.
When it happens
Trigger: Running `spacetime env set KEY VALUE` (or any verb other than `list`/`get`); typoing a subcommand such as `spacetime env put`.
Common situations: Developers expecting shell-like `env set` semantics after deploying; scripts ported from other tools that mutate env vars in place; typos in the env subcommand name.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot read environment schema: HTTP
- Environment key count exceeds limit
- Environment key is absent
- Environment key is both supplied and removed
- Environment key : shell input must be UTF-8
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/bb535115dba546ad.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/subcommands/env.rs:75
Self::Get(key) => {
// POSIX names cannot contain quotes or SQL syntax.
validate_key(key).map_err(|_| anyhow::anyhow!("Invalid environment key name"))?;
Ok(format!("SELECT value FROM st_env WHERE key = '{key}'"))
}
}
}
}
pub async fn exec(config: Config, args: &ArgMatches) -> anyhow::Result<()> {
let (command, args) = args.subcommand().context("Expected env get or list")?;
let query = match command {
"list" => Query::List,
"get" => Query::Get(
args.get_one::<String>("key")
.context("Expected environment key")?
.clone(),
),
_ => anyhow::bail!("Environment values can only be changed by publishing"),
};
query.sql()?;
let targets = load_config_db_targets(args.get_flag("no_config"))?;
let database = resolve_database_arg(
args.get_one::<String>("database").map(String::as_str),
targets.as_deref(),
"spacetime env get/list <database>",
)?;
let con = sql::parse_req(config, args, &database.database, database.server.as_deref()).await?;
let mut request = ClientApi::new(con).sql();
if let Some(confirmed) = args.get_one::<bool>("confirmed") {
request = request.query(&[("confirmed", confirmed)]);
}
print!("{}", fetch(request, query).await?);
Ok(())
}
async fn fetch(request: reqwest::RequestBuilder, query: Query) -> anyhow::Result<String> {View on GitHub (pinned to eddf9f5014)