{"record":{"id":"b72c619b4449ecf0","repo":"nautechsystems/nautilus_trader","slug":"label-contains-invalid-characters-only-alphanum","errorCode":null,"errorMessage":"{label} contains invalid characters (only alphanumeric and underscore allowed): {value}","messagePattern":"(.+?) contains invalid characters \\(only alphanumeric and underscore allowed\\): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/pg.rs","lineNumber":32,"sourceCode":"// -------------------------------------------------------------------------------------------------\n\nuse std::fmt::Debug;\n\nuse derive_builder::Builder;\nuse regex::Regex;\nuse serde::{Deserialize, Serialize};\nuse sqlx::{\n    AssertSqlSafe, ConnectOptions, PgPool,\n    postgres::{PgConnectOptions, PgConnection},\n};\n\nfn validate_sql_identifier(value: &str, label: &str) -> anyhow::Result<()> {\n    if value.is_empty() {\n        anyhow::bail!(\"{label} must not be empty\");\n    }\n\n    if !value.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {\n        anyhow::bail!(\n            \"{label} contains invalid characters (only alphanumeric and underscore allowed): {value}\"\n        );\n    }\n    Ok(())\n}\n\nfn escape_sql_string(value: &str) -> String {\n    value.replace('\\'', \"''\")\n}\n\n#[derive(Clone, Serialize, Deserialize, Builder)]\n#[serde(deny_unknown_fields)]\n#[builder(default)]\n#[cfg_attr(\n    feature = \"python\",\n    pyo3::pyclass(module = \"nautilus_trader.infrastructure\", from_py_object)\n)]\n#[cfg_attr(","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/pg.rs#L14-L50","documentation":"validate_sql_identifier() enforces that a SQL identifier used by init_postgres/drop_postgres contains only ASCII alphanumerics and underscores. Values containing hyphens, dots, spaces, or other characters are rejected to keep interpolated SQL safe and valid; the message includes the offending value and its label.","triggerScenarios":"Calling init_postgres or drop_postgres with an identifier argument (schema, table/catalog name, etc.) that contains characters outside [A-Za-z0-9_], e.g. schema \"my-schema\" or a table name with a dot.","commonSituations":"Deriving schema/table names from instance hostnames or container names that contain hyphens; using dots ('mydb.public') where a bare identifier is expected; quotes or spaces pasted into config values; multi-tenant names like 'tenant-42'.","solutions":["Rename the identifier to only letters, digits, and underscores (e.g. my_schema, tenant_42)","Sanitize the value before passing: replace invalid characters with '_' via the same rule the validator uses","If quoting is needed, use a proper Postgres identifier-quoting path instead of raw config values — but note this validator intentionally disallows that input","Read {label} and {value} in the message to find which config field to fix"],"exampleFix":"// before\nlet schema = format!(\"tenant-{}\", tenant_id); // hyphens rejected\n// after\nlet schema = format!(\"tenant_{}\", tenant_id.replace('-', \"_\"));\nassert!(schema.chars().all(|c| c.is_ascii_alphanumeric() || c == '_'));","handlingStrategy":"validation","validationCode":"fn sanitize_sql_identifier(v: &str) -> String {\n    v.chars().map(|c| if c.is_ascii_alphanumeric() || c == '_' { c } else { '_' }).collect()\n}\nlet schema = sanitize_sql_identifier(\"tenant-42\"); // \"tenant_42\"","typeGuard":"fn is_valid_sql_identifier(v: &str) -> bool {\n    !v.is_empty() && v.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')\n}\nassert!(is_valid_sql_identifier(&schema));","tryCatchPattern":"if let Err(e) = init_postgres(&opts) {\n    if e.to_string().contains(\"contains invalid characters\") {\n        return Err(anyhow::anyhow!(\"Fix Postgres identifier in config: {e}\"));\n    }\n    return Err(e);\n}","preventionTips":["Derive identifiers from safe inputs (UUIDs with underscores) rather than hostnames or display names","Run the alphanumeric+underscore check on all identifier config fields at startup","Replace hyphens/dots in externally sourced names (tenant IDs, container names) before using them as schema/table names"],"tags":["rust","postgresql","validation","identifier","sanitization"],"backgroundTag":"invalid-identifier-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}