{"record":{"id":"adebbe70a301819c","repo":"clockworklabs/SpacetimeDB","slug":"environment-key-name-config-input-must-be-a-string-boolean","errorCode":null,"errorMessage":"Environment key {name:?}: config input must be a string, boolean or JSON number","messagePattern":"Environment key (.+?): config input must be a string, boolean or JSON number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/publish/environment.rs","lineNumber":57,"sourceCode":"\npub(super) fn resolve(\n    schema: &EnvironmentSchema,\n    config: Option<&Value>,\n    mut shell: impl FnMut(&str) -> Option<OsString>,\n) -> anyhow::Result<Resolved> {\n    let mut resolved = Resolved {\n        values: BTreeMap::new(),\n        sources: BTreeMap::new(),\n    };\n    if let Some(config) = config {\n        let config = config.as_object().context(\"Environment config must be an object\")?;\n        for (name, value) in config {\n            spacetimedb_lib::environment::validate_key(name)?;\n            let value = match value {\n                Value::String(value) => value.clone(),\n                Value::Bool(value) => value.to_string(),\n                Value::Number(value) => value.to_string(),\n                _ => anyhow::bail!(\"Environment key {name:?}: config input must be a string, boolean or JSON number\"),\n            };\n            resolved.values.insert(name.clone(), value);\n            resolved.sources.insert(name.clone(), Source::Config);\n        }\n    }\n    // Lookup only the new artifact's declared names, never enumerate ambient values.\n    for declaration in schema.declarations() {\n        if let Some(value) = shell(&declaration.name) {\n            let value = value\n                .into_string()\n                .map_err(|_| anyhow::anyhow!(\"Environment key {:?}: shell input must be UTF-8\", declaration.name))?;\n            resolved.values.insert(declaration.name.clone(), value);\n            resolved.sources.insert(declaration.name.clone(), Source::Shell);\n        }\n    }\n    schema.validate_supplied_values(&resolved.values)?;\n    Ok(resolved)\n}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/subcommands/publish/environment.rs#L39-L75","documentation":"When publishing, environment values sourced from the spacetimedb config file must be JSON strings, booleans, or numbers. Other JSON types (arrays, objects, null) cannot be coerced to an environment string value, so `resolve` bails with this message naming the offending key.","triggerScenarios":"A config file's environment section contains a key whose value is an object, array, or null (e.g. `MY_KEY: {a: 1}` or `MY_KEY: null`) during `spacetime publish`.","commonSituations":"Copy-pasting structured config into the env section; forgetting to quote a value that YAML/JSON5 parses as an object or list; accidentally leaving `null` placeholders.","solutions":["Change the config value for the named key to a string, boolean, or number.","Quote structured values as strings if the literal text is intended (e.g. `MY_KEY: \"[1,2]\"`).","Remove null placeholders from the environment section."],"exampleFix":"// before (config)\nMY_KEY: {nested: true}\n// after (config)\nMY_KEY: \"nested=true\"","handlingStrategy":"validation","validationCode":"fn valid_env_value(v: &serde_json::Value) -> bool { matches!(v, serde_json::Value::String(_) | serde_json::Value::Bool(_) | serde_json::Value::Number(_)) }","typeGuard":"fn is_scalar_json(v: &serde_json::Value) -> bool { !matches!(v, serde_json::Value::Object(_) | serde_json::Value::Array(_) | serde_json::Value::Null) }","tryCatchPattern":"match result { Err(e) if e.to_string().contains(\"config input must be\") => { /* fix config value type for named key */ }, Err(e) => return Err(e), Ok(v) => v }","preventionTips":["Keep env config values scalar: strings, booleans, numbers only.","Quote any value that should be taken literally, especially bracketed or structured text.","Lint the env section for nulls and nested structures before publishing."],"tags":["environment","config","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}