{"record":{"id":"cc74c384653fe650","repo":"crewAIInc/crewAI","slug":"database-name-is-required-in-the-uri","errorCode":null,"errorMessage":"Database name is required in the URI","messagePattern":"Database name is required in the URI","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/mysql_loader.py","lineNumber":49,"sourceCode":"\n        query = source.source\n\n        parsed = urlparse(db_uri)\n        if parsed.scheme not in [\"mysql\", \"mysql+pymysql\"]:\n            raise ValueError(f\"Invalid MySQL URI scheme: {parsed.scheme}\")\n\n        connection_params = {\n            \"host\": parsed.hostname or \"localhost\",\n            \"port\": parsed.port or 3306,\n            \"user\": parsed.username,\n            \"password\": parsed.password,\n            \"database\": parsed.path.lstrip(\"/\") if parsed.path else None,\n            \"charset\": \"utf8mb4\",\n            \"cursorclass\": DictCursor,\n        }\n\n        if not connection_params[\"database\"]:\n            raise ValueError(\"Database name is required in the URI\")\n\n        try:\n            connection = connect(**connection_params)\n            try:\n                with connection.cursor() as cursor:\n                    cursor.execute(query)\n                    rows = cursor.fetchall()\n\n                    if not rows:\n                        content = \"No data found in the table\"\n                        return LoaderResult(\n                            content=content,\n                            metadata={\"source\": query, \"row_count\": 0},\n                            doc_id=self.generate_doc_id(\n                                source_ref=query, content=content\n                            ),\n                        )\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/mysql_loader.py#L31-L67","documentation":"Raised by MySQLLoader.load() when the db_uri parses but contains no database name — parsed.path is empty or only slashes, so database becomes None/empty after lstrip('/'). The loader requires the schema to be part of the URI because pymysql connects to a specific database and the code never issues USE.","triggerScenarios":"Passing 'mysql://user:pass@host:3306' (no /dbname); 'mysql://user:pass@host:3306/' (trailing slash only); URIs where the path segment was lost during templating or URL-encoding.","commonSituations":"Storing server coordinates in config and expecting the loader to take the database from a separate key; templating bugs that render an empty database placeholder (mysql://u:p@h:3306/); copy-paste from connection strings used by GUI clients that keep the database in a separate field.","solutions":["Append the database name to the URI: mysql://user:pass@host:3306/mydatabase.","Build the URI from parts with a check that db is non-empty before composing the string.","If the database name contains special characters, URL-encode it so the path still parses."],"exampleFix":"# before\nresult = MySQLLoader().load(src, metadata={'db_uri': 'mysql://u:p@h:3306'})\n\n# after\nresult = MySQLLoader().load(src, metadata={'db_uri': 'mysql://u:p@h:3306/app_db'})","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\\n\\ndef uri_has_database(uri: str) -> bool:\\n    return bool(urlparse(uri).path.lstrip('/'))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always compose URIs with an explicit /dbname.","Validate the path segment when building URIs from parts.","URL-encode database names with special characters."],"tags":["mysql","database","configuration","validation"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}