clockworklabs/SpacetimeDB · critical

required environment key is missing

Error message

required environment key is missing: {}

What it means

For RequiredEnvironmentValue types, the generated from_environment panics when the environment lookup returns None — i.e. the required key is absent from the process environment. The derive treats the variable as mandatory, so startup aborts with this message naming the key.

Solutions

  1. Set the required environment key in the module's deployment environment
  2. Fix the key name so it matches the declared identifier exactly
  3. Switch the derive/type to an optional value if the variable is genuinely optional

Example fix

// before
# .env
# API_KEY missing
// after
# .env
API_KEY=abcd1234
Defensive patterns

Strategy: try-catch

Validate before calling

for key in ["API_KEY", "DB_URL"] {
    if std::env::var(key).is_err() {
        eprintln!("missing required env key: {key}");
    }
}

Try / catch

// panic! cannot be caught; fail fast with your own preflight check:
fn preflight(required: &[&str]) -> Result<(), String> {
    let missing: Vec<_> = required.iter().filter(|k| std::env::var(k).is_err()).collect();
    if missing.is_empty() { Ok(()) } else { Err(format!("missing: {missing:?}")) }
}

Prevention

When it happens

Trigger: Running a SpacetimeDB module whose derived required environment type cannot find its key in the host-provided environment, e.g. the variable was never set in the deployment config.

Common situations: Forgetting to add the variable to the deployment environment/secrets; a typo in the key between the module declaration and the .env or platform config; renaming the key in code without updating ops configuration.

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/64ba86a6c42b51d5. Report an issue: GitHub.

Appendix: source

Thrown at crates/bindings-macro/src/environment/value.rs:90

        [value] => quote!(::spacetimedb::spacetimedb_lib::environment::EnvVarType::StringLiteral(#value.into())),
        values => quote!(::spacetimedb::spacetimedb_lib::environment::EnvVarType::Union(
            ::std::vec![#(#values.into()),*]
        )),
    };
    let ident = &item.ident;
    Ok(quote! {
        impl ::spacetimedb::rt::EnvironmentValue for #ident {
            const OPTIONAL: bool = false;

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

            fn from_environment(value: ::std::option::Option<::std::string::String>, key: &str) -> Self {
                match value.as_deref() {
                    #(::std::option::Option::Some(#values) => Self::#variants,)*
                    ::std::option::Option::Some(_) => ::core::panic!("environment value does not match its declared enum: {}", key),
                    ::std::option::Option::None => ::core::panic!("required environment key is missing: {}", key),
                }
            }
        }
        impl ::spacetimedb::rt::RequiredEnvironmentValue for #ident {}
    })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn rejects_invalid_enum_shapes_mappings_and_limits() {
        for input in [
            quote!(
                struct Value;
            ),
            quote!(

View on GitHub (pinned to eddf9f5014)