crewAIInc/crewAI · error · ValueError

Invalid PostgreSQL URI scheme: {parsed.scheme}

Error message

Invalid PostgreSQL URI scheme: {parsed.scheme}

What it means

Thrown by PGFileLoader when the db_uri parsed with urlparse has a scheme outside the allowlist ['postgresql', 'postgres', 'postgresql+psycopg2']. The scheme is everything before '://' in the URI. This guard runs before any network connection, so it fires purely on URI formatting.

Source

Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/postgres_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 PostgreSQL loader")

        query = source.source

        parsed = urlparse(db_uri)
        if parsed.scheme not in ["postgresql", "postgres", "postgresql+psycopg2"]:
            raise ValueError(f"Invalid PostgreSQL URI scheme: {parsed.scheme}")

        connection_params = {
            "host": parsed.hostname or "localhost",
            "port": parsed.port or 5432,
            "user": parsed.username,
            "password": parsed.password,
            "database": parsed.path.lstrip("/") if parsed.path else None,
            "cursor_factory": RealDictCursor,
        }

        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:
                    cursor.execute(query)

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use one of the three accepted prefixes: postgresql://user:pass@host:5432/db, postgres://..., or postgresql+psycopg2://...
  2. If you need asyncpg, note this loader only supports psycopg2 — use the psycopg2 scheme or a different loading path.
  3. Ensure the URI actually contains '://' so urlparse extracts the scheme correctly.
  4. Check for stray whitespace or quotes around the URI copied from env vars or config files.

Example fix

# before
metadata={"db_uri": "postgresql+asyncpg://user:pass@host/db"}  # rejected

# after
metadata={"db_uri": "postgresql://user:pass@host:5432/db"}  # accepted
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse

ALLOWED = {"postgresql", "postgres", "postgresql+psycopg2"}

def is_valid_pg_uri(uri: str) -> bool:
    return urlparse(uri).scheme in ALLOWED

Try / catch

try:
    result = pg_loader.load(src, metadata={"db_uri": uri})
except ValueError as e:
    if "Invalid PostgreSQL URI scheme" in str(e):
        fix_uri_scheme(e)  # log, alert config owner
    raise

Prevention

When it happens

Trigger: Passing URIs like mysql://..., sqlite://..., postgresql+asyncpg://..., or a URI with no scheme at all ('localhost:5432/db'), which urlparse parses with an empty scheme. Using the SQLAlchemy-style async driver 'postgresql+asyncpg' is rejected even though it looks valid.

Common situations: Copy-pasting a DSN from another service (Redis, MySQL) or from SQLAlchemy engine URLs; using connection strings produced by cloud platforms that prefix vendor-specific schemes; hand-building the URI and forgetting the scheme.

Related errors


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