{"record":{"id":"660c5d12c74b75ee","repo":"crewAIInc/crewAI","slug":"invalid-postgresql-uri-scheme-parsed-scheme","errorCode":null,"errorMessage":"Invalid PostgreSQL URI scheme: {parsed.scheme}","messagePattern":"Invalid PostgreSQL URI scheme: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/postgres_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 PostgreSQL loader\")\n\n        query = source.source\n\n        parsed = urlparse(db_uri)\n        if parsed.scheme not in [\"postgresql\", \"postgres\", \"postgresql+psycopg2\"]:\n            raise ValueError(f\"Invalid PostgreSQL URI scheme: {parsed.scheme}\")\n\n        connection_params = {\n            \"host\": parsed.hostname or \"localhost\",\n            \"port\": parsed.port or 5432,\n            \"user\": parsed.username,\n            \"password\": parsed.password,\n            \"database\": parsed.path.lstrip(\"/\") if parsed.path else None,\n            \"cursor_factory\": RealDictCursor,\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)","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/postgres_loader.py#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nmetadata={\"db_uri\": \"postgresql+asyncpg://user:pass@host/db\"}  # rejected\n\n# after\nmetadata={\"db_uri\": \"postgresql://user:pass@host:5432/db\"}  # accepted","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\n\nALLOWED = {\"postgresql\", \"postgres\", \"postgresql+psycopg2\"}\n\ndef is_valid_pg_uri(uri: str) -> bool:\n    return urlparse(uri).scheme in ALLOWED","typeGuard":null,"tryCatchPattern":"try:\n    result = pg_loader.load(src, metadata={\"db_uri\": uri})\nexcept ValueError as e:\n    if \"Invalid PostgreSQL URI scheme\" in str(e):\n        fix_uri_scheme(e)  # log, alert config owner\n    raise","preventionTips":["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."],"tags":["postgres","database","uri","validation"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}