psycopg/psycopg2 · error · TypeError
you can't specify both 'database' and 'dbname' arguments
Error message
you can't specify both 'database' and 'dbname' arguments
What it means
Raised by make_dsn() (lib/extensions.py:150-152) when both 'database' and 'dbname' are present in the keyword arguments. These are aliases for the same PostgreSQL connection parameter (libpq uses 'dbname'); psycopg2 accepts 'database' for familiarity but forbids specifying both to avoid ambiguity about which value wins.
Source
Thrown at lib/extensions.py:151
def getquoted(self, _null=b"NULL"):
return _null
def make_dsn(dsn=None, **kwargs):
"""Convert a set of keywords into a connection strings."""
if dsn is None and not kwargs:
return ''
# If no kwarg is specified don't mung the dsn, but verify it
if not kwargs:
parse_dsn(dsn)
return dsn
# Override the dsn with the parameters
if 'database' in kwargs:
if 'dbname' in kwargs:
raise TypeError(
"you can't specify both 'database' and 'dbname' arguments")
kwargs['dbname'] = kwargs.pop('database')
# Drop the None arguments
kwargs = {k: v for (k, v) in kwargs.items() if v is not None}
if dsn is not None:
tmp = parse_dsn(dsn)
tmp.update(kwargs)
kwargs = tmp
dsn = " ".join(["{}={}".format(k, _param_escape(str(v)))
for (k, v) in kwargs.items()])
# verify that the returned dsn is valid
parse_dsn(dsn)
return dsnView on GitHub (pinned to 3a6d9d6ddc)
Solutions
- Standardize on a single key: use 'dbname' everywhere (libpq native) or 'database' everywhere.
- When merging configs, drop one alias before calling connect/make_dsn: kwargs.pop('database', None).
- If using make_dsn(dsn, **kwargs), ensure the DSN string and kwargs don't each contribute a different alias.
Example fix
// before conn = psycopg2.connect(host=h, dbname='prod', database='prod') // after conn = psycopg2.connect(host=h, dbname='prod')
Defensive patterns
Strategy: validation
Validate before calling
if 'database' in kwargs and 'dbname' in kwargs:
raise TypeError('specify only one of database/dbname')
if 'database' in kwargs:
kwargs['dbname'] = kwargs.pop('database') Type guard
def has_duplicate_db_key(kwargs: dict) -> bool:
return 'database' in kwargs and 'dbname' in kwargs Try / catch
try:
conn = psycopg2.connect(**kwargs)
except TypeError as e:
if 'database' in str(e) and 'dbname' in str(e):
kwargs.pop('database', None)
conn = psycopg2.connect(**kwargs)
else: raise Prevention
- Standardize the whole codebase on one alias (prefer 'dbname').
- When merging configs from different layers, normalize to a single key.
When it happens
Trigger: Calling psycopg2.connect() or make_dsn() with both database=... and dbname=... in the same call, e.g. connect(dbname='x', database='y'), or passing a kwargs dict that merges two config sources each using a different alias.
Common situations: Merging a base DSN/kwargs (using 'dbname') with overrides (using 'database') from environment variables or a config file. Common when a framework uses 'database' (SQLAlchemy/ Django style) while the ops layer uses 'dbname' (libpq style).
Related errors
- pgrange must be a string or a RangeAdapter strict subclass
- pyrange must be a type or a Range strict subclass
- Composed elements must be Composable, got {i!r} instead
- Composed.join() argument must be a string or an SQL
- SQL values must be strings
AI-assisted analysis of psycopg/psycopg2@3a6d9d6ddc (2026-08-04).
Data as JSON: /data/errors/2463f02dd29c609f.json.
Report an issue: GitHub.