crewAIInc/crewAI · error · ValueError

Invalid MySQL URI scheme: {parsed.scheme}

Error message

Invalid MySQL URI scheme: {parsed.scheme}

What it means

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.

Source

Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/mysql_loader.py:36

        Args:
            source: SQL query (e.g., "SELECT * FROM table_name")
            **kwargs: Additional arguments including db_uri

        Returns:
            LoaderResult with database content
        """
        metadata = kwargs.get("metadata", {})
        db_uri = metadata.get("db_uri")

        if not db_uri:
            raise ValueError("Database URI is required for MySQL loader")

        query = source.source

        parsed = urlparse(db_uri)
        if parsed.scheme not in ["mysql", "mysql+pymysql"]:
            raise ValueError(f"Invalid MySQL URI scheme: {parsed.scheme}")

        connection_params = {
            "host": parsed.hostname or "localhost",
            "port": parsed.port or 3306,
            "user": parsed.username,
            "password": parsed.password,
            "database": parsed.path.lstrip("/") if parsed.path else None,
            "charset": "utf8mb4",
            "cursorclass": DictCursor,
        }

        if not connection_params["database"]:
            raise ValueError("Database name is required in the URI")

        try:
            connection = connect(**connection_params)
            try:
                with connection.cursor() as cursor:

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use exactly mysql://user:pass@host:3306/dbname or mysql+pymysql://user:pass@host:3306/dbname.
  2. If your stored URI uses another MySQL driver scheme, rewrite the scheme before passing it: uri.replace('mysql+mysqlconnector://', 'mysql+pymysql://').
  3. For Postgres sources use PostgresLoader with its own URI format instead of MySQLLoader.

Example fix

# before
result = MySQLLoader().load(src, metadata={'db_uri': 'postgresql://u:p@h:5432/db'})

# after
result = MySQLLoader().load(src, metadata={'db_uri': 'mysql+pymysql://u:p@h:3306/db'})
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse\n\ndef is_mysql_uri(uri: str) -> bool:\n    return urlparse(uri).scheme in {'mysql', 'mysql+pymysql'}

Prevention

When it happens

Trigger: 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://'.

Common situations: 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.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/f2945b58555ae21a. Report an issue: GitHub.