nautechsystems/nautilus_trader · error
{label} contains invalid characters (only alphanumeric and u
Error message
{label} contains invalid characters (only alphanumeric and underscore allowed): {value} What it means
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.
Source
Thrown at crates/infrastructure/src/sql/pg.rs:32
// -------------------------------------------------------------------------------------------------
use std::fmt::Debug;
use derive_builder::Builder;
use regex::Regex;
use serde::{Deserialize, Serialize};
use sqlx::{
AssertSqlSafe, ConnectOptions, PgPool,
postgres::{PgConnectOptions, PgConnection},
};
fn validate_sql_identifier(value: &str, label: &str) -> anyhow::Result<()> {
if value.is_empty() {
anyhow::bail!("{label} must not be empty");
}
if !value.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
anyhow::bail!(
"{label} contains invalid characters (only alphanumeric and underscore allowed): {value}"
);
}
Ok(())
}
fn escape_sql_string(value: &str) -> String {
value.replace('\'', "''")
}
#[derive(Clone, Serialize, Deserialize, Builder)]
#[serde(deny_unknown_fields)]
#[builder(default)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(module = "nautilus_trader.infrastructure", from_py_object)
)]
#[cfg_attr(View on GitHub (pinned to 18893faf8b)
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
Example fix
// before
let schema = format!("tenant-{}", tenant_id); // hyphens rejected
// after
let schema = format!("tenant_{}", tenant_id.replace('-', "_"));
assert!(schema.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')); Defensive patterns
Strategy: validation
Validate before calling
fn sanitize_sql_identifier(v: &str) -> String {
v.chars().map(|c| if c.is_ascii_alphanumeric() || c == '_' { c } else { '_' }).collect()
}
let schema = sanitize_sql_identifier("tenant-42"); // "tenant_42" Type guard
fn is_valid_sql_identifier(v: &str) -> bool {
!v.is_empty() && v.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
}
assert!(is_valid_sql_identifier(&schema)); Try / catch
if let Err(e) = init_postgres(&opts) {
if e.to_string().contains("contains invalid characters") {
return Err(anyhow::anyhow!("Fix Postgres identifier in config: {e}"));
}
return Err(e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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'.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- {label} must not be empty
- Failed to start execution intent reservation: {e}
- Failed to reserve execution intent for signer {} on chain {}
- Failed to record prepared execution intent: {e}
- Failed to commit execution intent reservation: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b72c619b4449ecf0.
Report an issue: GitHub.