crewAIInc/crewAI · error · ValueError

Failed to load data from PostgreSQL: {e}

Error message

Failed to load data from PostgreSQL: {e}

What it means

The catch-all ValueError from PGFileLoader for any non-database exception during loading — most often connection failures raised before or during psycopg connect(): unknown hostname, refused connection, authentication failure, or missing psycopg driver. It wraps the original exception, so __cause__ carries the real reason.

Source

Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/postgres_loader.py:101

                    if len(content) > 100000:
                        content = content[:100000] + "\n\n[Content truncated...]"

                    return LoaderResult(
                        content=content,
                        metadata={
                            "source": query,
                            "database": connection_params["database"],
                            "row_count": len(rows),
                            "columns": columns,
                        },
                        doc_id=self.generate_doc_id(source_ref=query, content=content),
                    )
            finally:
                connection.close()
        except Error as e:
            raise ValueError(f"PostgreSQL database error: {e}") from e
        except Exception as e:
            raise ValueError(f"Failed to load data from PostgreSQL: {e}") from e

View on GitHub (pinned to 754d7323be)

Solutions

  1. Inspect the wrapped exception: except ValueError as e: print(e.__cause__) to get the underlying connection error.
  2. Verify connectivity out-of-band: psql 'postgresql://user:pass@host:5432/db' -c 'select 1' from the same machine/container.
  3. URL-encode special characters in the password (use urllib.parse.quote) or avoid them in the URI.
  4. If the server requires TLS, append ?sslmode=require to the URI.
  5. From Docker, replace localhost with the service name or host.docker.internal as appropriate.

Example fix

# before
db_uri = "postgresql://user:p@ssw0rd@host:5432/db"  # '@' in password breaks parsing

# after
from urllib.parse import quote
db_uri = f"postgresql://user:{quote('p@ssw0rd')}@host:5432/db"
Defensive patterns

Strategy: retry

Validate before calling

import psycopg

def can_connect(db_uri: str) -> bool:
    try:
        with psycopg.connect(db_uri, connect_timeout=5):
            return True
    except Exception:
        return False

Try / catch

for attempt in range(3):
    try:
        result = pg_loader.load(src, metadata=md)
        break
    except ValueError as e:
        if "Failed to load" in str(e) and is_transient(e.__cause__):
            backoff(attempt)
            continue
        raise

Prevention

When it happens

Trigger: Network-level failures: host unreachable, wrong port, postgres not running, TLS requirement mismatch, or psycopg.OperationalError on bad credentials that is not an instance of the caught Error class path. Also triggered if the psycopg package itself is missing or incompatible.

Common situations: Connecting from a container to a DB on 'localhost' when the DB runs on the host (need host.docker.internal); DB behind a VPN not connected; password with special characters not URL-encoded in the URI; server requires SSL (sslmode=require) which the bare URI omits.

Related errors


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