AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

BaseChatModel.Agenerate Masks Non-Exception BaseException With AttributeError

When a callback is attached and a BaseException (not Exception) like asyncio.CancelledError or KeyboardInterrupt is raised inside _agenerate, the cleanup code attempts to access .generations on the exception object, masking the original error with AttributeError.

highConfidence 95%LangChainAffected Vlangchain-Core==1.4.8

Origin Analysis

In BaseChatModel.agenerate, results from asyncio.gather are checked with isinstance(res, BaseException) to collect failures, but the subsequent on_llm_end filtering uses the narrower isinstance(res, Exception). Non-Exception BaseExceptions pass the filter, and the code then accesses res.generations, causing AttributeError.
1. Define a custom BaseException subclass (not Exception). 2. Create a subclass of BaseChatModel that raises this exception in _agenerate. 3. Call agenerate on the model with any callback handler attached (so run_managers are truthy). 4. Observe that instead of the original exception, an AttributeError is raised because the exception object lacks 'generations'.

Fixing Code Block

Edge Case Audit

This change broadens error reporting to include all BaseExceptions. Ensure that `on_llm_error` implementations can safely handle BaseException types, particularly `asyncio.CancelledError`, without catching and suppressing them inappropriately. If issues arise, the original behavior can be restored by re-adding the `isinstance(res, Exception)` guard. Also, audit other code paths (e.g., synchronous generate) for similar mismatched exception checks.

Ecosystem Topology