{"id":"c79c51faf88e8ee9","repo":"sqlalchemy/sqlalchemy","slug":"s-is-not-among-the-defined-enum-values-enum-na","errorCode":null,"errorMessage":"'%s' is not among the defined enum values. Enum name: %s. Possible values: %s","messagePattern":"'(.+?)' is not among the defined enum values\\. Enum name: (.+?)\\. Possible values: (.+?)","errorType":"exception","errorClass":"LookupError","httpStatus":null,"severity":"error","filePath":"lib/sqlalchemy/sql/sqltypes.py","lineNumber":1824,"sourceCode":"    def native(self):  # type: ignore[override]\n        return self.native_enum\n\n    def _db_value_for_elem(self, elem):\n        try:\n            return self._valid_lookup[elem]\n        except KeyError as err:\n            # for unknown string values, we return as is.  While we can\n            # validate these if we wanted, that does not allow for lesser-used\n            # end-user use cases, such as using a LIKE comparison with an enum,\n            # or for an application that wishes to apply string tests to an\n            # ENUM (see [ticket:3725]).  While we can decide to differentiate\n            # here between an INSERT statement and a criteria used in a SELECT,\n            # for now we're staying conservative w/ behavioral changes (perhaps\n            # someone has a trigger that handles strings on INSERT)\n            if not self.validate_strings and isinstance(elem, str):\n                return elem\n            else:\n                raise LookupError(\n                    \"'%s' is not among the defined enum values. \"\n                    \"Enum name: %s. Possible values: %s\"\n                    % (\n                        elem,\n                        self.name,\n                        langhelpers.repr_tuple_names(self.enums),\n                    )\n                ) from err\n\n    class Comparator(String.Comparator[str]):\n        __slots__ = ()\n\n        type: String\n\n        def _adapt_expression(\n            self,\n            op: OperatorType,\n            other_comparator: TypeEngine.Comparator[Any],","sourceCodeStart":1806,"sourceCodeEnd":1842,"githubUrl":"https://github.com/sqlalchemy/sqlalchemy/blob/d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff/lib/sqlalchemy/sql/sqltypes.py#L1806-L1842","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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)."],"exampleFix":"// before\nstatus = Enum('new', 'done', validate_strings=True)\nsession.add(Model(status='archived'))  # not in enum\n// after\nstatus = Enum('new', 'done', 'archived', validate_strings=True)","handlingStrategy":"validation","validationCode":"def validate_enum_value(enum_type, value):\n    if value is None:\n        return value\n    allowed = list(enum_type.enums)\n    if value not in allowed:\n        raise ValueError(\n            \"%r is not a valid value for Enum %s; allowed: %s\"\n            % (value, enum_type.name, allowed)\n        )\n    return value\n\n# usage: validate_enum_value(MyTable.status.type, user_input) before insert","typeGuard":"def is_valid_enum_value(enum_type, value):\n    return value is None or value in enum_type.enums","tryCatchPattern":"from sqlalchemy.exc import LookupError\n\ntry:\n    session.execute(table.insert().values(status=user_input))\n    session.commit()\nexcept LookupError as e:\n    # user_input was not among the defined enum values\n    session.rollback()\n    report_invalid_enum(user_input, MyTable.status.type.enums)","preventionTips":["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."],"tags":["sqlalchemy","enum","sqltypes","validation","lookuperror","bind"],"analyzedSha":"d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff","analyzedAt":"2026-08-01T17:20:52.075Z","schemaVersion":2}