clockworklabs/SpacetimeDB · error

required environment key is missing

Error message

required environment key is missing: {key}

What it means

RequiredEnvironmentValue::from_environment unwraps the Option<String> supplied by the host and panics if it is None. It marks an environment variable as mandatory: unlike plain EnvironmentValue, absence is a hard error rather than a fallback. The panic names the missing key so the developer knows which variable to set.

Solutions

  1. Set the missing environment variable for the database before publishing or calling the module (e.g. `spacetime set <db> <key> <value>` or the equivalent CLI env subcommand).
  2. Use Option<T> as the field type if the variable is genuinely optional, which falls back to None instead of panicking.
  3. Provide a default via a custom EnvironmentValue implementation with a default instead of RequiredEnvironmentValue.
  4. Audit the module's declared env keys against the deployment environment during CI.

Example fix

// before
#[spacetimedb(env)]
api_key: String, // panics if unset
// after
#[spacetimedb(env)]
api_key: Option<String>,
let api_key = api_key.unwrap_or_else(|| "dev-default".into());
Defensive patterns

Strategy: validation

Validate before calling

assert!(std::env::var("API_KEY").is_ok() || db_env_get("API_KEY").is_some(), "API_KEY must be set before publish");

Try / catch

let key = Option::<String>::from_environment(host_value, "API_KEY");

Prevention

When it happens

Trigger: Declaring a module config/env field of a type implementing RequiredEnvironmentValue (e.g. String) and publishing/running the module without that environment variable set in the database environment.

Common situations: Deploying a module to a new database and forgetting to run `spacetime env set KEY ...` / set the variable in the publisher config; renaming a key in code but not in the deployment environment.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/bindings/src/rt.rs:955

    fn get(environment: &crate::Environment, key: &str) -> Self {
        Self::from_environment(environment.get(key), key)
    }
}

/// Required environment types supported by the optional-value implementation.
/// Derived enums and `String` implement this; `Option<T>` deliberately does not.
#[doc(hidden)]
pub trait RequiredEnvironmentValue: EnvironmentValue {}

impl EnvironmentValue for String {
    const OPTIONAL: bool = false;

    fn constraint() -> spacetimedb_lib::environment::EnvVarType {
        spacetimedb_lib::environment::EnvVarType::String
    }

    fn from_environment(value: Option<String>, key: &str) -> Self {
        value.unwrap_or_else(|| panic!("required environment key is missing: {key}"))
    }
}

impl RequiredEnvironmentValue for String {}

impl<T: RequiredEnvironmentValue> EnvironmentValue for Option<T> {
    const OPTIONAL: bool = true;

    fn constraint() -> spacetimedb_lib::environment::EnvVarType {
        T::constraint()
    }

    fn from_environment(value: Option<String>, key: &str) -> Self {
        value.map(|value| T::from_environment(Some(value), key))
    }
}

mod string_environment_value_sealed {

View on GitHub (pinned to eddf9f5014)