AsyncUnitOfWork.register_repository() calls self._session_handler.scoped_session() during __init__, storing the resolved AsyncSession for the current asyncio.current_task() scope directly in each repository's _external_session.
If the UnitOfWork is kept alive across multiple asyncio tasks (e.g. as a singleton in a DI container), all repositories remain permanently bound to the session that was active at creation time. In SQLAlchemy 2.0, once that session's transaction is closed via an explicit begin() + commit(), autobegin is disabled on it. Every subsequent invocation then raises InvalidRequestError: Autobegin is disabled on this Session; please call session.begin() to start a new transaction, because the stale session is reused instead of a fresh one being resolved for the new task scope.
The workaround is to force AsyncUnitOfWork to be re-instantiated on every use (e.g. via a Factory provider rather than a Singleton), but this defeats the purpose of async_scoped_session with asyncio.current_task as the scope function, which is designed to handle per-task session isolation automatically.