sqlalchemy/sqlalchemy · error · LookupError
'%s' is not among the defined enum values. Enum name: %s. Po
Error message
'%s' is not among the defined enum values. Enum name: %s. Possible values: %s
What it means
This LookupError is raised in Enum._db_value_for_elem (sqltypes.py:1824) when converting a Python value to its database representation and the value is not found in the enum's lookup table, AND either validate_strings=True is set or the value is not a string. When validate_strings is False (the default), unknown string values are passed through unchanged to allow LIKE comparisons and trigger-based inserts; non-string unknown values, or any unknown value when validate_strings=True, trigger this error. The message includes the offending value, the enum's name, and the list of valid values.
Source
Thrown at lib/sqlalchemy/sql/sqltypes.py:1824
def native(self): # type: ignore[override]
return self.native_enum
def _db_value_for_elem(self, elem):
try:
return self._valid_lookup[elem]
except KeyError as err:
# for unknown string values, we return as is. While we can
# validate these if we wanted, that does not allow for lesser-used
# end-user use cases, such as using a LIKE comparison with an enum,
# or for an application that wishes to apply string tests to an
# ENUM (see [ticket:3725]). While we can decide to differentiate
# here between an INSERT statement and a criteria used in a SELECT,
# for now we're staying conservative w/ behavioral changes (perhaps
# someone has a trigger that handles strings on INSERT)
if not self.validate_strings and isinstance(elem, str):
return elem
else:
raise LookupError(
"'%s' is not among the defined enum values. "
"Enum name: %s. Possible values: %s"
% (
elem,
self.name,
langhelpers.repr_tuple_names(self.enums),
)
) from err
class Comparator(String.Comparator[str]):
__slots__ = ()
type: String
def _adapt_expression(
self,
op: OperatorType,
other_comparator: TypeEngine.Comparator[Any],View on GitHub (pinned to d9b44cb731)
Solutions
- Ensure the value being inserted is one of the declared enum values (or a member of the enum.Enum class the type was built from).
- If you intentionally store arbitrary strings, remove validate_strings=True (the default passes unknown strings through).
- Add the missing value to the Enum definition or migrate the column's allowed values to include it.
- Validate/coerce user input against the enum set before binding (e.g. via a Pydantic/enum validator).
Example fix
// before
status = Enum('new', 'done', validate_strings=True)
session.add(Model(status='archived')) # not in enum
// after
status = Enum('new', 'done', 'archived', validate_strings=True) Defensive patterns
Strategy: validation
Validate before calling
def validate_enum_value(enum_type, value):
if value is None:
return value
allowed = list(enum_type.enums)
if value not in allowed:
raise ValueError(
"%r is not a valid value for Enum %s; allowed: %s"
% (value, enum_type.name, allowed)
)
return value
# usage: validate_enum_value(MyTable.status.type, user_input) before insert Type guard
def is_valid_enum_value(enum_type, value):
return value is None or value in enum_type.enums Try / catch
from sqlalchemy.exc import LookupError
try:
session.execute(table.insert().values(status=user_input))
session.commit()
except LookupError as e:
# user_input was not among the defined enum values
session.rollback()
report_invalid_enum(user_input, MyTable.status.type.enums) Prevention
- Set validate_strings=True on Enum types so invalid strings are caught at bind time rather than silently stored.
- Validate user input against enum_type.enums before issuing INSERT/UPDATE statements.
- Keep a single canonical list of allowed values and derive both the Enum definition and the UI/validation from it.
When it happens
Trigger: Inserting/setting a column value that is not one of the declared enum values while validate_strings=True is enabled on the Enum type. Inserting a non-string (e.g. an int or object) that does not map to any enum element. Calling the bind processor with such a value. The exact raise happens in the except KeyError branch of _db_value_for_elem after the _valid_lookup miss.
Common situations: Enabling Enum(..., validate_strings=True) to catch bad data at the Python layer, then feeding user input that includes values outside the enum set. Storing integers or other types into an Enum column expecting implicit conversion. Drift between an application's allowed values and the SQLAlchemy Enum definition (e.g. new enum members added to the DB but not to the model).
Related errors
- When provided, length must be larger or equal than the lengt
- TypeEngine.as_generic() heuristic is undefined for types tha
- Not a boolean value: %r
- update parameter dictionary must not be empty
- storage_format must be an enum of type VectorStorageFormat
AI-assisted analysis of sqlalchemy/sqlalchemy@d9b44cb731 (2026-08-01).
Data as JSON: /data/errors/c79c51faf88e8ee9.json.
Report an issue: GitHub.