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
- Use one of the three accepted prefixes: postgresql://user:pass@host:5432/db, postgres://..., or postgresql+psycopg2://...
- If you need asyncpg, note this loader only supports psycopg2 — use the psycopg2 scheme or a different loading path.
- Ensure the URI actually contains '://' so urlparse extracts the scheme correctly.
- 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
- Build URIs from components with a helper that always emits 'postgresql://'.
- Reject asyncpg/SQLAlchemy-generic DSNs at your config layer if this loader is the consumer.
- Add a startup config lint that runs urlparse on all DB URIs.
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
- Database name is required in the URI
- Project name cannot be empty
- Project name '{name}' produces invalid folder name '{folder_
- Database URI is required for MySQL loader
- Invalid MySQL URI scheme: {parsed.scheme}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/660c5d12c74b75ee.
Report an issue: GitHub.