{"record":{"id":"26d597a8a3a93f67","repo":"influxdata/influxdb","slug":"invalid-database-name-db-name","errorCode":null,"errorMessage":"invalid database name: {db_name}","messagePattern":"invalid database name: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"influxdb3_processing_engine/src/worker/local.rs","lineNumber":617,"sourceCode":"            error!(error = %ErrorOneLine(error), ?self.trigger_definition, %context, \"error running plugin\");\n        }\n    }\n\n    /// Handles the return state from the plugin, writing back lines and handling any errors.\n    /// It returns a vec of error messages that can be used to log or report back to the user.\n    async fn handle_return_state(\n        &self,\n        plugin_return_state: influxdb3_py_api::system_py::PluginReturnState,\n    ) -> Vec<anyhow::Error> {\n        let ingest_time = SystemTime::now()\n            .duration_since(SystemTime::UNIX_EPOCH)\n            .unwrap();\n\n        let mut errors = Vec::new();\n\n        for (db_name, lines) in plugin_return_state.write_db_lines {\n            let Ok(database_name) = DatabaseName::new(db_name.clone()) else {\n                errors.push(anyhow!(\"invalid database name: {db_name}\"));\n                continue;\n            };\n\n            if let Err(e) = self\n                .write_endpoint\n                .write_lp(\n                    WriteTarget::User(database_name),\n                    lines.join(\"\\n\").as_str(),\n                    Time::from_timestamp_nanos(ingest_time.as_nanos() as i64),\n                    false,\n                )\n                .await\n                .with_context(|| format!(\"error writing back lines to {db_name}\"))\n            {\n                errors.push(e);\n            }\n        }\n","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_processing_engine/src/worker/local.rs#L599-L635","documentation":"After a WAL plugin runs, its return state may contain writes the plugin wants routed to databases (write_db_lines). Before writing line protocol, each database name is validated with DatabaseName::new. If the plugin returned a database name that is not a valid InfluxDB database identifier, the write is skipped for that entry, an error is recorded, and processing continues with the remaining writes.","triggerScenarios":"A plugin's process_writes (or scheduled call) return state includes an entry in write_db_lines whose key is empty, contains invalid characters (spaces, illegal punctuation), or otherwise fails DatabaseName validation when the worker calls write_lp for each (db_name, lines) pair.","commonSituations":"Python plugin builds the database name by string concatenation (e.g. db = f'{prefix}-{suffix}' producing an empty or malformed name), a mapping/config lookup returns None converted to an invalid string, or a typo in a hardcoded database name.","solutions":["Fix the plugin to return only valid database names: non-empty, allowed characters, no leading/trailing whitespace.","Validate the database name inside the plugin before adding it to write_db_lines.","Log the plugin return state during development to confirm the exact db_name string produced.","If the name comes from user input or config, sanitize/normalize it before constructing the write."],"exampleFix":"# before\nresult[\"write_db_lines\"] = {f\"{tenant}_{thing}\": lines}\n# after\nfrom influxdb3 import validate_database_name\nname = f\"{tenant}_{thing}\"\nif validate_database_name(name):\n    result[\"write_db_lines\"] = {name: lines}\nelse:\n    influxdb3_local.error(f\"invalid database name: {name}\")","handlingStrategy":"validation","validationCode":"def write_to_db(name, lines):\n    if not name or any(c in name for c in ' -/\\\\,.:;!?@#$%^&*()+={}[]|<>\"\\''):\n        raise ValueError(f\"invalid database name: {name}\")\n    result[\"write_db_lines\"] = {name: lines}","typeGuard":"def is_valid_db_name(name) -> bool:\n    return isinstance(name, str) and len(name) > 0 and name == name.strip()","tryCatchPattern":"# plugin host records the error per-db and continues; monitor the error stream\nfor err in run_errors:\n    if \"invalid database name\" in str(err):\n        alert(f\"plugin emitted bad db name: {err}\")","preventionTips":["Validate database names inside plugins before adding to write_db_lines","Avoid building db names by raw string concatenation of user input","Log plugin return state during development","Use constants for database names instead of dynamic construction"],"tags":["rust","processing-engine","plugin","validation","database-name"],"backgroundTag":"invalid-identifier-format","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}