{"record":{"id":"befb0cbf273269cd","repo":"jdx/mise","slug":"postgres-database-must-contain-only-letters-numbers-and","errorCode":null,"errorMessage":"Postgres database must contain only letters, numbers, and underscores","messagePattern":"Postgres database must contain only letters, numbers, and underscores","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/daemons/presets.rs","lineNumber":92,"sourceCode":"        }\n    }\n    let database = preset\n        .options\n        .get(\"database\")\n        .map(|value| {\n            value\n                .as_str()\n                .ok_or_else(|| eyre::eyre!(\"options.database must be a string\"))\n        })\n        .transpose()?\n        .unwrap_or(\"postgres\");\n    // This name is also used as a URI component and SQL identifier.\n    if database.is_empty()\n        || !database\n            .chars()\n            .all(|c| c.is_ascii_alphanumeric() || c == '_')\n    {\n        bail!(\"Postgres database must contain only letters, numbers, and underscores\");\n    }\n    let data = state_dir(root).join(\"data\").join(name);\n    let mut context = tera::Context::new();\n    context.insert(\"data\", &quote(data.to_string_lossy()));\n    context.insert(\"port\", &port);\n    context.insert(\"database\", database);\n    let mut renderer = crate::tera::get_tera(Some(root));\n    let mut table = preset.daemon;\n    for (_, value) in table.iter_mut() {\n        if let toml::Value::String(text) = value {\n            *text = crate::tera::render_str(&mut renderer, text, &context)?;\n        }\n    }\n    if let Some(toml::Value::String(command)) = table.get_mut(\"ready_cmd\") {\n        *command = format!(\n            \"{} x -- sh -c {}\",\n            quote(crate::env::MISE_BIN.to_string_lossy()),\n            quote(command.as_str())","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/daemons/presets.rs#L74-L110","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\ndatabase = \"my-db\"\n# after\ndatabase = \"my_db\"","handlingStrategy":"validation","validationCode":"const validDb = (db) => /^[A-Za-z0-9_]+$/.test(db);","typeGuard":"const isSafeDbName = (v) => typeof v === 'string' && v.length > 0 && /^[A-Za-z0-9_]+$/.test(v);","tryCatchPattern":null,"preventionTips":["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"],"tags":["daemon","postgres","validation","naming"],"backgroundTag":"invalid-identifier-format","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}