{"record":{"id":"b613f096c9cdd79a","repo":"clockworklabs/SpacetimeDB","slug":"invalid-json5-configuration","errorCode":null,"errorMessage":"Invalid JSON5 configuration","messagePattern":"Invalid JSON5 configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/spacetime_config/environment.rs","lineNumber":89,"sourceCode":"            strings.push(json5::from_str(&content[start..i]).map_err(|_| anyhow::anyhow!(\"Invalid JSON5 string\"))?);\n        }\n    }\n    // Check decoded strings as well: Unicode escapes must not manufacture an\n    // internal marker and cause a string to be interpreted as a number.\n    let mut prefix = \"__spacetime_numeric_\".to_owned();\n    while content.contains(&prefix) || strings.iter().any(|s| s.contains(&prefix)) {\n        prefix.push('_');\n    }\n    let mut text = String::with_capacity(content.len());\n    let mut previous = 0;\n    for (index, (start, end)) in replacements.into_iter().enumerate() {\n        text.push_str(&content[previous..start]);\n        text.push_str(&format!(\"\\\"{prefix}{index}\\\"\"));\n        previous = end;\n    }\n    text.push_str(&content[previous..]);\n    // Parser diagnostics may quote the source line, which can contain secrets.\n    let mut value: Value = json5::from_str(&text).map_err(|_| anyhow::anyhow!(\"Invalid JSON5 configuration\"))?;\n    restore(&mut value, &prefix, &numbers, None)?;\n    Ok(value)\n}\n\n/// Deserialize through JSON text so Serde's flattened-field buffer does not\n/// receive visit_u128 from Value's deserializer. That buffer cannot represent\n/// u128, while the arbitrary-precision JSON parser preserves its decimal token.\n/// Diagnostics discard values while retaining a bounded, ordinary unknown field\n/// name, which is useful for correcting misspelled configuration options.\npub(super) fn decode_config(value: Value) -> anyhow::Result<super::SpacetimeConfig> {\n    let encoded = serde_json::to_vec(&value).map_err(|_| anyhow::anyhow!(\"Invalid configuration structure\"))?;\n    serde_json::from_slice(&encoded).map_err(|error| {\n        let diagnostic = error.to_string();\n        if let Some((field, suffix)) = diagnostic\n            .strip_prefix(\"unknown field `\")\n            .and_then(|message| message.split_once('`'))\n            && suffix.starts_with(\", expected \")\n            && !field.is_empty()","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/spacetime_config/environment.rs#L71-L107","documentation":"After masking numeric literals and strings, the parser re-parses the reconstructed JSON5 text into a JSON Value. If that final parse fails, the config is rejected with this opaque message — deliberately vague because JSON5 parser diagnostics may echo source lines containing secrets.","triggerScenarios":"Structurally invalid JSON5 config: missing commas, unbalanced braces/brackets, trailing garbage, or numeric placeholder corruption after masking.","commonSituations":"Hand-edited configs with syntax mistakes; comment or comma typos; editors leaving stray characters in spacetimedb config files.","solutions":["Validate the config's JSON5 syntax with a linter/JSON5 parser.","Fix missing commas, braces, or brackets around the edited section.","Temporarily test with `json5.parse()` locally to locate the line, since the CLI hides diagnostics to protect secrets."],"exampleFix":"// before (config)\n{ env: { A: 1 B: 2 } }\n// after (config)\n{ env: { A: 1, B: 2 } }","handlingStrategy":"validation","validationCode":"// validate overall JSON5 structure before invoking the CLI\nconst json5 = require('json5');\njson5.parse(fs.readFileSync(configPath, 'utf8')); // throws with line info locally","typeGuard":null,"tryCatchPattern":"match result { Err(e) if e.to_string() == \"Invalid JSON5 configuration\" => { eprintln!(\"Structural syntax error in config; validate with a local JSON5 parser\"); }, Err(e) => return Err(e), Ok(v) => v }","preventionTips":["Lint the config with a JSON5 parser/editor plugin after each edit.","Fix commas, braces, and brackets before publishing; the CLI hides diagnostics to protect secrets.","Keep machine-generated configs under syntax tests."],"tags":["config","json5","parse-error"],"backgroundTag":"config-file-parse-error","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"}