{"id":"f9b86f2e7261b72b","repo":"sqlalchemy/alembic","slug":"no-such-index-s","errorCode":null,"errorMessage":"No such index: '%s'","messagePattern":"No such index: '(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"alembic/operations/batch.py","lineNumber":710,"sourceCode":"                # type-bound constraints are only included in the new\n                # table via their type object in any case, so ignore the\n                # drop_constraint() that comes here via the\n                # Operations.implementation_for(alter_column)\n                return\n            raise ValueError(\"No such constraint: '%s'\" % const.name)\n        else:\n            if isinstance(const, PrimaryKeyConstraint):\n                for col in const.columns:\n                    self.columns[col.name].primary_key = False\n\n    def create_index(self, idx: Index) -> None:\n        self.new_indexes[idx.name] = idx  # type: ignore[index]\n\n    def drop_index(self, idx: Index) -> None:\n        try:\n            del self.indexes[idx.name]  # type: ignore[arg-type]\n        except KeyError:\n            raise ValueError(\"No such index: '%s'\" % idx.name)\n\n    def rename_table(self, *arg, **kw):\n        raise NotImplementedError(\"TODO\")\n","sourceCodeStart":692,"sourceCodeEnd":714,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/44fb3450330204b222ff05135e1fbbbdb28c44db/alembic/operations/batch.py#L692-L714","documentation":"Raised by ApplyBatchImpl.drop_index() when del self.indexes[idx.name] raises KeyError. The index name supplied to batch_op.drop_index() is not among the indexes reflected/copied from the target table, so batch mode cannot remove it from the rebuild plan.","triggerScenarios":"Inside batch_alter_table, calling batch_op.drop_index('idx_name') where 'idx_name' is not an index on the table; dropping an index already dropped; index name typo or quoting/case mismatch.","commonSituations":"Migration referencing an index removed in another branch/revision; index named via naming convention in metadata but reflected under a different name; running migrations out of order against a DB whose state doesn't match.","solutions":["Reflect the table's actual indexes and use the real name.","Verify the index has not already been dropped earlier in this migration or a prior revision.","Add an existence guard before calling batch_op.drop_index()."],"exampleFix":"// before\nwith op.batch_alter_table('user') as batch_op:\n    batch_op.drop_index('ix_user_nonexistent')  # raises ValueError\n\n// after\nfrom sqlalchemy import inspect\nindex_names = [i['name'] for i in inspect(op.get_bind()).get_indexes('user')]\nwith op.batch_alter_table('user') as batch_op:\n    if 'ix_user_email' in index_names:\n        batch_op.drop_index('ix_user_email')","handlingStrategy":"validation","validationCode":"from sqlalchemy import inspect\n\ndef index_exists(bind, table, name) -> bool:\n    return name in {i['name'] for i in inspect(bind).get_indexes(table)}","typeGuard":null,"tryCatchPattern":"try:\n    batch_op.drop_index(name)\nexcept ValueError as e:\n    if 'No such index' in str(e):\n        pass  # already absent\n    else:\n        raise","preventionTips":["Reflect indexes and verify names before dropping in batch mode.","Guard drops to keep migrations idempotent.","Check that the index wasn't dropped in a prior revision."],"tags":["alembic","batch-mode","indexes","migrations"],"analyzedSha":"44fb3450330204b222ff05135e1fbbbdb28c44db","analyzedAt":"2026-08-04T19:57:10.248Z","schemaVersion":2}