sqlalchemy/alembic · error · TypeError
'type' can be one of %s
Error message
'type' can be one of %s
What it means
Raised by SchemaObjects.generic_constraint() when the type_ argument is not one of the allowed keys ('foreignkey','primary','unique','check',None). The method maps type_ to a SQLAlchemy constraint constructor via a dict; an unknown type raises TypeError listing the valid values. generic_constraint is the internal factory used to render drop_constraint and similar ops.
Source
Thrown at alembic/operations/schemaobj.py:179
table_name: str,
type_: str | None,
schema: str | None = None,
**kw,
) -> Any:
t = self.table(table_name, schema=schema)
types: dict[str | None, Any] = {
"foreignkey": lambda name: sa_schema.ForeignKeyConstraint(
[], [], name=name
),
"primary": sa_schema.PrimaryKeyConstraint,
"unique": sa_schema.UniqueConstraint,
"check": lambda name: sa_schema.CheckConstraint("", name=name),
None: sa_schema.Constraint,
}
try:
const = types[type_]
except KeyError as ke:
raise TypeError(
"'type' can be one of %s"
% ", ".join(sorted(repr(x) for x in types))
) from ke
else:
const = const(name=name)
t.append_constraint(const)
return const
def metadata(self) -> MetaData:
kw = {}
if (
self.migration_context is not None
and "target_metadata" in self.migration_context.opts
):
mt = self.migration_context.opts["target_metadata"]
if hasattr(mt, "naming_convention"):
kw["naming_convention"] = mt.naming_convention
return sa_schema.MetaData(**kw)View on GitHub (pinned to 44fb345033)
Solutions
- Pass one of the valid type_ values: 'foreignkey', 'primary', 'unique', 'check', or None.
- Build the op via the high-level API (op.drop_constraint(..., type_='foreignkey')) which documents the accepted strings.
- Validate the type_ string against the allowed set before calling generic_constraint().
Example fix
// before
schema_obj.generic_constraint('c', 'user', type_='foreign') # raises TypeError
// after
schema_obj.generic_constraint('c', 'user', type_='foreignkey') Defensive patterns
Strategy: validation
Validate before calling
VALID_CONSTRAINT_TYPES = {'foreignkey', 'primary', 'unique', 'check', None}
def validate_constraint_type(type_):
if type_ not in VALID_CONSTRAINT_TYPES:
raise ValueError(f'invalid constraint type {type_!r}; expected one of {VALID_CONSTRAINT_TYPES}')
return type_ Type guard
def is_valid_constraint_type(type_) -> bool:
return type_ in {'foreignkey', 'primary', 'unique', 'check', None} Try / catch
try:
schema_obj.generic_constraint(name, table, type_=t)
except TypeError as e:
if "'type' can be one of" in str(e):
# map/correct the type string
schema_obj.generic_constraint(name, table, type_=normalized_t)
else:
raise Prevention
- Use the documented type_ strings: 'foreignkey','primary','unique','check'.
- Validate type_ against the allowed set before calling generic_constraint.
- Build ops via the high-level API to get correct type normalization.
When it happens
Trigger: Calling schema_obj.generic_constraint(name, table, type_='bogus') with an invalid type; a DropConstraintOp whose constraint_type is not normalized to one of the allowed values feeding into generic_constraint; typos like 'foreign' instead of 'foreignkey', 'uniq' instead of 'unique', 'pk' instead of 'primary'.
Common situations: Custom code that constructs constraint type strings manually; an op object built with an unsupported type string; version skew where a new constraint type isn't registered.
Related errors
- constraint cannot be produced; original constraint is not pr
- Constraint must have a name
- No such constraint: '%s'
- operation is not reversible; original column is not present
- This MigrationScript instance has a multiple-entry list for
AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04).
Data as JSON: /data/errors/4808b48ab6281f33.json.
Report an issue: GitHub.