{"record":{"id":"b1f0a9e5fcdab077","repo":"sqlalchemy/alembic","slug":"cannot-call-run-async-with-a-sync-engine","errorCode":null,"errorMessage":"Cannot call run_async with a sync engine","messagePattern":"Cannot call run_async with a sync engine","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"alembic/operations/base.py","lineNumber":579,"sourceCode":"        transaction as the connection running in the migration context.\n\n        Any additional arg or kw_arg passed to this function are passed\n        to the provided async function.\n\n        .. versionadded: 1.11\n\n        .. note::\n\n            This method can be called only when alembic is called using\n            an async dialect.\n        \"\"\"\n        if not sqla_compat.sqla_14_18:\n            raise NotImplementedError(\"SQLAlchemy 1.4.18+ required\")\n        sync_conn = self.get_bind()\n        if sync_conn is None:\n            raise NotImplementedError(\"Cannot call run_async in SQL mode\")\n        if not sync_conn.dialect.is_async:\n            raise ValueError(\"Cannot call run_async with a sync engine\")\n        from sqlalchemy.ext.asyncio import AsyncConnection\n        from sqlalchemy.util import await_only\n\n        async_conn = AsyncConnection._retrieve_proxy_for_target(sync_conn)\n        return await_only(async_function(async_conn, *args, **kw_args))\n\n\nclass Operations(AbstractOperations):\n    \"\"\"Define high level migration operations.\n\n    Each operation corresponds to some schema migration operation,\n    executed against a particular :class:`.MigrationContext`\n    which in turn represents connectivity to a database,\n    or a file output stream.\n\n    While :class:`.Operations` is normally configured as\n    part of the :meth:`.EnvironmentContext.run_migrations`\n    method called from an ``env.py`` script, a standalone","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/operations/base.py#L561-L597","documentation":"Operations.run_async raises ValueError when the underlying connection's dialect is not async (sync_conn.dialect.is_async is False). run_async wraps an AsyncConnection derived from a synchronous proxy that only exists for async-configured engines; a plain sync engine has no async proxy to retrieve.","triggerScenarios":"Calling op.run_async(fn) in a migration whose engine was created with a sync driver (e.g. psycopg2, mysql+pymysql) rather than an async driver (e.g. postgresql+asyncpg, mysql+aiomysql).","commonSituations":"Switching a project to asyncpg but env.py still creates a sync engine; mixing sync alembic runs with run_async calls; tests using a sync SQLite engine while migrations assume async.","solutions":["Configure env.py to create an async engine (create_async_engine) and run migrations via connection.run_sync().","Use an async DBAPI driver in sqlalchemy.asyncio.create_async_engine (e.g. asyncpg, aiomysql).","If you must use a sync engine, replace run_async with synchronous logic on op.get_bind()."],"exampleFix":"# before: sync engine in env.py\nengine = create_engine('postgresql+psycopg2://...')\n\n# after: async engine\nfrom sqlalchemy.ext.asyncio import create_async_engine\nengine = create_async_engine('postgresql+asyncpg://...')\n# then run migrations with connection.run_sync(do_run_migrations)","handlingStrategy":"validation","validationCode":"def run_async_safe(op, fn, *args, **kw):\n    bind = op.get_bind()\n    if bind is None or not bind.dialect.is_async:\n        raise ValueError('run_async requires an async engine')\n    return op.run_async(fn, *args, **kw)","typeGuard":"def engine_is_async(bind) -> bool:\n    return bool(getattr(getattr(bind, 'dialect', None), 'is_async', False))","tryCatchPattern":null,"preventionTips":["Create the engine with sqlalchemy.ext.asyncio.create_async_engine for async migrations.","Use an async DBAPI driver (asyncpg, aiomysql, aiosqlite).","Verify bind.dialect.is_async before invoking run_async in shared migration code."],"tags":["run-async","async","engine","dialect"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}