{"record":{"id":"f2945b58555ae21a","repo":"crewAIInc/crewAI","slug":"invalid-mysql-uri-scheme-parsed-scheme","errorCode":null,"errorMessage":"Invalid MySQL URI scheme: {parsed.scheme}","messagePattern":"Invalid MySQL URI scheme: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/mysql_loader.py","lineNumber":36,"sourceCode":"\n        Args:\n            source: SQL query (e.g., \"SELECT * FROM table_name\")\n            **kwargs: Additional arguments including db_uri\n\n        Returns:\n            LoaderResult with database content\n        \"\"\"\n        metadata = kwargs.get(\"metadata\", {})\n        db_uri = metadata.get(\"db_uri\")\n\n        if not db_uri:\n            raise ValueError(\"Database URI is required for MySQL loader\")\n\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:","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/mysql_loader.py#L18-L54","documentation":"Raised by MySQLLoader.load() when the scheme of the parsed db_uri is not 'mysql' or 'mysql+pymysql'. urlparse is applied to the URI and only those two schemes are accepted, so PostgreSQL URIs (postgresql://), SQLAlchemy variants (mysql+mysqlconnector://), missing schemes (host/db is parsed with scheme='host-path' or empty), or typos all fail here.","triggerScenarios":"Passing 'postgresql://...' or 'mysql+mysqlconnector://...'; a URI without a scheme like 'user:pass@localhost:3306/mydb' (urlparse treats 'user:pass@localhost:3306' oddly and scheme won't be mysql); URI strings with leading whitespace or a typo like 'mysq://'.","commonSituations":"Reusing a SQLAlchemy DATABASE_URL from another service across different engine drivers; copy-paste between PostgresLoader and MySQLLoader; secrets managers returning URIs formatted for a different client; local dev with URIs assembled by hand.","solutions":["Use exactly mysql://user:pass@host:3306/dbname or mysql+pymysql://user:pass@host:3306/dbname.","If your stored URI uses another MySQL driver scheme, rewrite the scheme before passing it: uri.replace('mysql+mysqlconnector://', 'mysql+pymysql://').","For Postgres sources use PostgresLoader with its own URI format instead of MySQLLoader."],"exampleFix":"# before\nresult = MySQLLoader().load(src, metadata={'db_uri': 'postgresql://u:p@h:5432/db'})\n\n# after\nresult = MySQLLoader().load(src, metadata={'db_uri': 'mysql+pymysql://u:p@h:3306/db'})","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\\n\\ndef is_mysql_uri(uri: str) -> bool:\\n    return urlparse(uri).scheme in {'mysql', 'mysql+pymysql'}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on mysql+pymysql:// in config for all services.","Rewrite other driver schemes to mysql+pymysql before loading.","Keep separate loader choices per database engine."],"tags":["mysql","database","configuration","validation"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}