valeriansaliou/sonic · critical · panic

syntax error in config

Error message

syntax error in config

What it means

After loading the raw config, Config::parse deserializes it into ServerConfigTemp and panics with "syntax error in config" if the structure doesn't match the expected server configuration schema. This is a deserialization/type error: a required field is missing or has the wrong type, not a literal syntax failure.

Source

Thrown at server/src/config.rs:102

            .build()
            .expect("error reading config");

        // `#[serde(flatten)]` breaks type coercion from the `config` crate,
        // so we can’t have `crate::Config` define
        // `#[serde(flatten)] sonic: sonic::Config`. It’s a bit dirty but at
        // least we don’t have to manually add custom deserialization logic to
        // all non-string fields (in the core!).
        #[derive(serde::Deserialize)]
        pub struct ServerConfigTemp {
            pub channel: ConfigChannel,
            pub server: ConfigServer,
        }

        // Parse configuration.
        let mut server_config = raw_config
            .clone()
            .try_deserialize::<ServerConfigTemp>()
            .expect("syntax error in config");
        let mut core_config = raw_config
            .try_deserialize::<sonic::Config>()
            .expect("syntax error in config");

        back_compat::migrate_channel_search(&mut server_config.channel, &mut core_config);

        // Validate configuration.
        core_config.validate();

        Config {
            channel: server_config.channel,
            server: server_config.server,
            sonic: Arc::new(core_config),
        }
    }
}

pub fn read_config(custom_path: Option<&str>) -> Config {

View on GitHub (pinned to e6a72da6a5)

Solutions

  1. Compare your config against the current ServerConfigTemp schema / example config for your sonic version
  2. Check field types: numbers, booleans, and strings must match the Rust types
  3. Ensure all required sections ([server], etc.) are present
  4. Read the full panic message: the config crate error printed by expect includes the exact field that failed

Example fix

// before
[server]
port = "1491"        # string, expected integer
// after
[server]
port = 1491
Defensive patterns

Strategy: validation

Validate before calling

// Rust: deserialize a dry-run copy first to get a precise error message
let raw = load_raw_config()?;
match raw.clone().try_deserialize::<ServerConfigTemp>() {
    Ok(_) => (),
    Err(e) => eprintln!("bad server config: {}", e),
}

Try / catch

match raw.try_deserialize::<ServerConfigTemp>() {
    Ok(cfg) => cfg,
    Err(e) => { eprintln!("config field error: {}", e); std::process::exit(1); }
}

Prevention

When it happens

Trigger: Calling Config::parse when the config value cannot be deserialized into ServerConfigTemp — missing required sections (e.g. [server]), wrong field types (string where int expected), unknown/misspelled keys under strict deserialization.

Common situations: Hand-edited config files after upgrades; config schemas changed between sonic versions; env vars injecting strings into numeric fields.

Related errors


AI-assisted analysis of valeriansaliou/sonic@e6a72da6a5 (2026-09-01). Data as JSON: /api/errors/26013edf7bbcbcca. Report an issue: GitHub.