huggingface/smolagents · warning · AgentError

Agent interrupted.

Error message

Agent interrupted.

What it means

Agents support graceful interruption via an interrupt_switch; when it is set (e.g. by agent.interrupt()), the ReAct loop in _run_stream raises AgentError('Agent interrupted.') at the top of the next step instead of continuing.

Source

Thrown at src/smolagents/agents.py:547

            return RunResult(
                output=output,
                token_usage=token_usage,
                steps=step_dicts,
                timing=Timing(start_time=run_start_time, end_time=time.time()),
                state=state,
            )

        return output

    def _run_stream(
        self, task: str, max_steps: int, images: list["PIL.Image.Image"] | None = None
    ) -> Generator[ActionStep | PlanningStep | FinalAnswerStep | ChatMessageStreamDelta]:
        self.step_number = 1
        returned_final_answer = False
        while not returned_final_answer and self.step_number <= max_steps:
            if self.interrupt_switch:
                raise AgentError("Agent interrupted.", self.logger)

            # Run a planning step if scheduled
            if self.planning_interval is not None and (
                self.step_number == 1 or (self.step_number - 1) % self.planning_interval == 0
            ):
                planning_start_time = time.time()
                planning_step = None
                for element in self._generate_planning_step(
                    task, is_first_step=len(self.memory.steps) == 1, step=self.step_number
                ):  # Don't use the attribute step_number here, because there can be steps from previous runs
                    yield element
                    planning_step = element
                assert isinstance(planning_step, PlanningStep)  # Last yielded element should be a PlanningStep
                planning_end_time = time.time()
                planning_step.timing = Timing(
                    start_time=planning_start_time,
                    end_time=planning_end_time,
                )

View on GitHub (pinned to 30bb116109)

Solutions

  1. Catch AgentError in the run loop and check whether it's an interruption if you need to distinguish it from failures
  2. Call interrupt() only from a different thread than the one running agent.run()
  3. If run() keeps going, note the switch is checked between steps: wait for the current step to finish

Example fix

# before
threading.Thread(target=agent.run, args=(task,)).start()
agent.interrupt()  # raises AgentError('Agent interrupted.') inside run

# after
try:
    agent.run(task)
except AgentError as e:
    if "interrupted" in str(e):
        logger.info("Run cancelled by user")
    else:
        raise
Defensive patterns

Strategy: try-catch

Try / catch

from smolagents import AgentError
try:
    result = agent.run(task)
except AgentError as e:
    if "interrupted" in str(e):
        handle_cancelled()
    else:
        raise

Prevention

When it happens

Trigger: Calling agent.interrupt() (or setting agent.interrupt_switch = True) from another thread/callback while agent.run(...) is executing; the loop checks the switch before each step, so a long LLM call finishes before the error surfaces.

Common situations: Cancelling a runaway agent from a UI, timeout watchdog thread, or gradio button; interrupting during a long tool execution (the current step completes first).

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/c6aeeba10bb30da8. Report an issue: GitHub.