{"record":{"id":"62f1e89bfaf73b01","repo":"clockworklabs/SpacetimeDB","slug":"invalid-environment-key-name","errorCode":null,"errorMessage":"Invalid environment key name","messagePattern":"Invalid environment key name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/env.rs","lineNumber":59,"sourceCode":"            ),\n        ))\n        .subcommand(target(\n            Command::new(\"list\").about(\"List published environment keys and values\"),\n        ))\n}\n\n#[derive(Clone)]\nenum Query {\n    List,\n    Get(String),\n}\nimpl Query {\n    fn sql(&self) -> anyhow::Result<String> {\n        match self {\n            Self::List => Ok(\"SELECT key, value FROM st_env\".into()),\n            Self::Get(key) => {\n                // POSIX names cannot contain quotes or SQL syntax.\n                validate_key(key).map_err(|_| anyhow::anyhow!(\"Invalid environment key name\"))?;\n                Ok(format!(\"SELECT value FROM st_env WHERE key = '{key}'\"))\n            }\n        }\n    }\n}\n\npub async fn exec(config: Config, args: &ArgMatches) -> anyhow::Result<()> {\n    let (command, args) = args.subcommand().context(\"Expected env get or list\")?;\n    let query = match command {\n        \"list\" => Query::List,\n        \"get\" => Query::Get(\n            args.get_one::<String>(\"key\")\n                .context(\"Expected environment key\")?\n                .clone(),\n        ),\n        _ => anyhow::bail!(\"Environment values can only be changed by publishing\"),\n    };\n    query.sql()?;","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/subcommands/env.rs#L41-L77","documentation":"The `spacetime env get` subcommand builds a SQL query embedding the key into a WHERE clause. Before doing so it runs validate_key, which enforces POSIX-style names (no quotes or SQL metacharacters); a failing key aborts with this error to prevent SQL injection into the st_env query.","triggerScenarios":"Running `spacetime env get <key>` where <key> contains quotes, spaces, semicolons, or other characters disallowed by validate_key — or is empty.","commonSituations":"Copy-pasting keys with surrounding quotes from documentation or JSON, keys containing dashes/paths set via other tooling, or shell quoting mistakes injecting extra characters.","solutions":["Re-run with a bare POSIX-style key: letters, digits, underscores (e.g. MY_API_KEY), no quotes.","Use `spacetime env list` to see the exact valid key names, then copy one verbatim.","Remove shell-added quotes: pass the key unquoted/unescaped in the command.","Fix upstream tooling that writes non-conforming keys into st_env."],"exampleFix":"// before\nspacetime env get \"MY_KEY\"\n// after\nspacetime env get MY_KEY","handlingStrategy":"validation","validationCode":"const keyOk = /^[A-Za-z_][A-Za-z0-9_]*$/.test(key); if (!keyOk) throw new Error(`Key must be POSIX-style (letters, digits, underscore): ${key}`);","typeGuard":null,"tryCatchPattern":"// shell: validate before invoking\n[[ \"$KEY\" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || { echo \"invalid key\" >&2; exit 1; }","preventionTips":["Pass keys without quotes or shell escaping","Use `spacetime env list` to copy exact key names","Restrict st_env keys to POSIX identifier characters when setting them"],"tags":["cli","validation","sql","environment"],"backgroundTag":"invalid-identifier-format","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"}