{"record":{"id":"39957b1568ddd4ae","repo":"valeriansaliou/sonic","slug":"error-reading-config","errorCode":null,"errorMessage":"error reading config","messagePattern":"error reading config","errorType":"validation","errorClass":"panic","httpStatus":null,"severity":"critical","filePath":"server/src/config.rs","lineNumber":85,"sourceCode":"impl Config {\n    pub fn parse(source: impl ::config::Source + Send + Sync + 'static) -> Self {\n        // Read configuration.\n        let raw_config: config::Config = config::Config::builder()\n            // Start from defaults.\n            .add_source(config::File::from_str(\n                defaults_toml(),\n                config::FileFormat::Toml,\n            ))\n            // Merge static configuration (from file).\n            .add_source(source)\n            // Merge environment overrides.\n            .add_source(\n                config::Environment::with_prefix(\"SONIC\")\n                    .separator(\"__\")\n                    .prefix_separator(\"_\"),\n            )\n            .build()\n            .expect(\"error reading config\");\n\n        // `#[serde(flatten)]` breaks type coercion from the `config` crate,\n        // so we can’t have `crate::Config` define\n        // `#[serde(flatten)] sonic: sonic::Config`. It’s a bit dirty but at\n        // least we don’t have to manually add custom deserialization logic to\n        // all non-string fields (in the core!).\n        #[derive(serde::Deserialize)]\n        pub struct ServerConfigTemp {\n            pub channel: ConfigChannel,\n            pub server: ConfigServer,\n        }\n\n        // Parse configuration.\n        let mut server_config = raw_config\n            .clone()\n            .try_deserialize::<ServerConfigTemp>()\n            .expect(\"syntax error in config\");\n        let mut core_config = raw_config","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/valeriansaliou/sonic/blob/e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2/server/src/config.rs#L67-L103","documentation":" sonic-server's Config::parse builds a figment/config value from file sources plus SONIC_-prefixed environment variables and calls .expect(\"error reading config\"). This panics when the config crate cannot even load/assemble the raw configuration — before any deserialization — typically because a configured file is missing/unreadable or an environment source is malformed.","triggerScenarios":"Calling Config::parse (directly or via Task/PendingTask startup) when the config file passed (or its default location) does not exist, cannot be read, has invalid syntax at the source level, or a SONIC_* env var cannot be merged.","commonSituations":"Wrong --config path on startup; file permissions; env vars like SONIC_SERVER__LOG_LEVEL with values that break source building; missing config file in container images.","solutions":["Verify the config file path passed to the server exists and is readable","Check env var naming: prefix SONIC_, nesting separator __ (e.g. SONIC_SERVER__LOG_LEVEL)","Validate the config file syntax (JSON/YAML/TOML matches the format figment detects by extension)","Run with a minimal known-good config to isolate which source fails"],"exampleFix":"// before\nSONIC_SERVER_LOG_LEVEL=debug   # wrong nesting separator\n// after\nSONIC_SERVER__LOG_LEVEL=debug","handlingStrategy":"validation","validationCode":"// Rust: pre-flight check before starting the server\nlet path = std::path::Path::new(&config_path);\nif !path.exists() { panic!(\"config file not found: {}\", config_path); }\nfor (k, _) in std::env::vars().filter(|(k, _)| k.starts_with(\"SONIC_\")) {\n    // env keys must use SONIC_ prefix and __ nesting separator\n}","typeGuard":null,"tryCatchPattern":"// Run Config::parse in a guarded startup path and print the source error\nlet conf = std::panic::catch_unwind(Config::parse)\n    .map_err(|p| format!(\"config load failed: {:?}\", p))?;","preventionTips":["Always pass an explicit --config path and verify it exists in your launcher script","Use SONIC_ prefix with __ (double underscore) for nested env overrides","Keep a known-good example config in the repo and diff against it on failures","Validate config file syntax with the appropriate linter (TOML/YAML/JSON) in CI"],"tags":["rust","configuration","startup","environment"],"backgroundTag":"config-load-failed","analyzedSha":"e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2","analyzedAt":"2026-09-01T14:10:00.384Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}