Errors and interruptions¶
Mistakes in your code¶
A wrong use of the library raises TypeError or ValueError as early as possible: when you create the Agent, apply
@tool or @loop, or call a method. The message says what is wrong, how to fix it, and gives an example:
TypeError: @loop needs both until and limit
Fix: set both
Example:
@loop(until=State.is_answered, limit=50)
Errors from outside¶
Every exception below inherits from AlpineAgentsError.
| Exception | Raised when |
|---|---|
RateLimitError |
The provider returned 429 after the SDK's retries |
AuthError |
The API key is missing or rejected |
ContextTooLongError |
The request is larger than the model's context window. Add compact_if_full to the loop |
ProviderError |
Any other provider failure. The three above are subclasses of it |
OutputError |
ask(returns=...) did not get a valid answer after its retries, or compact got an empty summary |
NoHumanError |
ask_human was called on an Agent with human=None |
MCPConnectionError |
An MCP server could not connect, or the connection was lost |
For ProviderError and MCPConnectionError, the original exception is in __cause__.
Nothing is swallowed¶
Exceptions from tools, from the loop body and from until functions propagate as they are. alpineagents does not
catch them or turn them into results. To let the model handle a failure, return it from the tool as a string. See
Tools.
The State after an exception¶
| The exception happens in | The State afterwards |
|---|---|
think |
The context is as it was before think. state.turn does not change |
use_tools |
Results of the calls that finished are recorded. The other calls stay pending |
Anything, and leaves run |
The error is recorded in state.history. Pending calls are closed with a result such as (aborted: TimeoutError) |
After run raises, state.stopped_by is None, and you can call run with the same State again. agent is the
Agent from the quick start:
import time
from alpineagents import RateLimitError, State
state = State("Find the bug in main.py")
try:
agent.run(state)
except RateLimitError:
time.sleep(60)
agent.run(state)
Catch an exception inside the loop body¶
If the loop body catches an exception from use_tools, the calls that did not finish stay pending, and the next
think raises ValueError. Close them with state.deny first:
try:
agent.use_tools(state)
except TimeoutError:
for call in state.pending_calls:
state.deny(call, "The tool timed out")
Ctrl+C and cancellation¶
- Ctrl+C during
runcloses pending calls with the result(interrupted by user).run(state)continues from there. - A sync tool that is still running keeps running in its thread. If it finishes later, the model gets its result as a
notice at the next
think. - In async code, cancelling the task follows the same rules. See Async.