jdx/mise · error
Postgres database must contain only letters, numbers, and…
Error message
Postgres database must contain only letters, numbers, and underscores
What it means
The postgres database option is used both as a URI component and as a SQL identifier, so expand validates it up front: it must be non-empty and contain only ASCII letters, digits, and underscores. Anything else is rejected before any files or processes are touched.
Solutions
- Rename the database to use only letters, numbers, and underscores (e.g. my_db)
- Remove characters like '-', '.', or spaces from the database value
- Ensure the database key is non-empty
Example fix
# before database = "my-db" # after database = "my_db"
Defensive patterns
Strategy: validation
Validate before calling
const validDb = (db) => /^[A-Za-z0-9_]+$/.test(db);
Type guard
const isSafeDbName = (v) => typeof v === 'string' && v.length > 0 && /^[A-Za-z0-9_]+$/.test(v);
Prevention
- Use snake_case for database names
- Never include hyphens, dots, or spaces in the database option
- Validate generated names with the same regex before committing config
When it happens
Trigger: A daemon preset config sets a database name containing hyphens, dots, spaces, or other non-alphanumeric characters, or an empty database string, and expand validates it.
Common situations: Naming a database 'my-db' or 'my.db' (hyphens/dots rejected); quoting or whitespace accidentally included in the TOML string; leaving database = "" in the config.
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.
Related errors
- invalid database name
- failed to create database
- firewall rule name ' ' must contain only ASCII letters…
- incompatible data in (stored , current ); migrate or reset…
- initdb and postgres have incompatible versions
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/befb0cbf273269cd.
Report an issue: GitHub.
Appendix: source
Thrown at src/daemons/presets.rs:92
}
}
let database = preset
.options
.get("database")
.map(|value| {
value
.as_str()
.ok_or_else(|| eyre::eyre!("options.database must be a string"))
})
.transpose()?
.unwrap_or("postgres");
// This name is also used as a URI component and SQL identifier.
if database.is_empty()
|| !database
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_')
{
bail!("Postgres database must contain only letters, numbers, and underscores");
}
let data = state_dir(root).join("data").join(name);
let mut context = tera::Context::new();
context.insert("data", "e(data.to_string_lossy()));
context.insert("port", &port);
context.insert("database", database);
let mut renderer = crate::tera::get_tera(Some(root));
let mut table = preset.daemon;
for (_, value) in table.iter_mut() {
if let toml::Value::String(text) = value {
*text = crate::tera::render_str(&mut renderer, text, &context)?;
}
}
if let Some(toml::Value::String(command)) = table.get_mut("ready_cmd") {
*command = format!(
"{} x -- sh -c {}",
quote(crate::env::MISE_BIN.to_string_lossy()),
quote(command.as_str())View on GitHub (pinned to 533346cc37)