Skip to content

Interrupt a running Anthropic session before archiving it - #71465

Merged
kaxil merged 1 commit into
mainfrom
anthropic-interrupt-before-archive
Aug 13, 2026
Merged

kaxil merged 1 commit into
mainfrom
anthropic-interrupt-before-archive

Conversation

@kaxil

@kaxil kaxil commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

Problem

The API refuses to archive or delete a session while its status is running, rejecting
both with a 400. AnthropicAgentSessionOperator treats archiving as best-effort teardown on
every failure path, so a session that will not stop on its own is left behind with no way to
release it -- and it keeps accruing active_seconds, which the SDK describes as the
duration the session's runtime cost is priced on.

Evidence

Two sessions halted by a $0.01 budget sat at status running for over 40 minutes. Model
spend was frozen at the ceiling, but active_seconds kept climbing across successive
samples (777 to 838 seconds over one 60-second window). Both archive and delete returned
400. Sending user.interrupt moved them to idle immediately, after which archiving
succeeded.

Solution

AnthropicHook.archive_session now interrupts and retries when the first archive attempt
fails, and interrupt_session exposes the event on its own. The retry is bounded, so a
session that genuinely cannot be archived still surfaces its error rather than looping.

This is reachable well beyond budgets: any session still working when a task fails, times
out, or is killed hits the same 400. A budget halt just makes it routine, because that is a
session which has stopped spending without stopping.

Scope

The interrupt-then-archive sequence was verified by hand against the live API on two
genuinely stuck sessions. Its wiring through archive_session is covered by unit tests
rather than a live run.

@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from ca5d7c3 to 7977439 Compare August 11, 2026 19:58
@kaxil
kaxil marked this pull request as ready for review August 11, 2026 20:00
@kaxil
kaxil requested a review from gopidesupavan as a code owner August 11, 2026 20:00
@kaxil
kaxil requested a review from Lee-W August 11, 2026 20:00
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 7977439 to 360e983 Compare August 11, 2026 21:03
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 360e983 to 89b5c74 Compare August 11, 2026 21:33
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 89b5c74 to 4196cb2 Compare August 11, 2026 21:42
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 4196cb2 to 1b66210 Compare August 12, 2026 06:38
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 1b66210 to 976ccd9 Compare August 12, 2026 08:38
Comment thread providers/anthropic/tests/unit/anthropic/hooks/test_anthropic.py Outdated
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch 2 times, most recently from 897fd16 to cc595b2 Compare August 12, 2026 13:10
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from cc595b2 to 6b9eafa Compare August 12, 2026 13:46
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 6b9eafa to d3eb6bb Compare August 13, 2026 08:42
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from d3eb6bb to 4625697 Compare August 13, 2026 09:45
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 4625697 to ae679de Compare August 13, 2026 12:05
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from ae679de to 9c0e263 Compare August 13, 2026 12:05
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 9c0e263 to 8eebd5b Compare August 13, 2026 12:20
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 8eebd5b to 56057b6 Compare August 13, 2026 13:45
Base automatically changed from anthropic-agent-config-docs to main August 13, 2026 13:46
The API refuses to archive **or** delete a session while its status is
``running``, rejecting both with a 400. ``AnthropicAgentSessionOperator``
treats archiving as best-effort teardown on every failure path, so a
session that will not stop on its own is left behind with no way to
release it -- and it keeps accruing ``active_seconds``, which the SDK
describes as the duration the session's runtime cost is priced on.

Observed directly: two sessions halted by a $0.01 budget sat at status
``running`` for over 40 minutes with model spend frozen at the ceiling
while ``active_seconds`` kept climbing. ``archive`` and ``delete`` both
returned 400. Sending ``user.interrupt`` moved them to ``idle``
immediately, after which archiving succeeded.

``AnthropicHook.archive_session`` now interrupts and retries when the
first archive attempt fails, and ``interrupt_session`` exposes the event
on its own. The retry is bounded, so an unarchivable session still
surfaces its error rather than looping.

This is reachable well beyond budgets -- any session still working when a
task fails, times out, or is killed hits the same 400 -- but a budget halt
makes it routine, because that is a session which has stopped spending
without stopping.

The interrupt-then-archive sequence was verified by hand against the live
API on two genuinely stuck sessions. Its wiring through
``archive_session`` is covered by unit tests rather than a live run.
@kaxil
kaxil force-pushed the anthropic-interrupt-before-archive branch from 56057b6 to 1c1076b Compare August 13, 2026 13:46
@kaxil
kaxil merged commit 2db44d0 into main Aug 13, 2026
5 checks passed
@kaxil
kaxil deleted the anthropic-interrupt-before-archive branch August 13, 2026 13:48
dabla pushed a commit to dabla/airflow that referenced this pull request Aug 14, 2026
The API refuses to archive **or** delete a session while its status is
``running``, rejecting both with a 400. ``AnthropicAgentSessionOperator``
treats archiving as best-effort teardown on every failure path, so a
session that will not stop on its own is left behind with no way to
release it -- and it keeps accruing ``active_seconds``, which the SDK
describes as the duration the session's runtime cost is priced on.

Observed directly: two sessions halted by a $0.01 budget sat at status
``running`` for over 40 minutes with model spend frozen at the ceiling
while ``active_seconds`` kept climbing. ``archive`` and ``delete`` both
returned 400. Sending ``user.interrupt`` moved them to ``idle``
immediately, after which archiving succeeded.

``AnthropicHook.archive_session`` now interrupts and retries when the
first archive attempt fails, and ``interrupt_session`` exposes the event
on its own. The retry is bounded, so an unarchivable session still
surfaces its error rather than looping.

This is reachable well beyond budgets -- any session still working when a
task fails, times out, or is killed hits the same 400 -- but a budget halt
makes it routine, because that is a session which has stopped spending
without stopping.

The interrupt-then-archive sequence was verified by hand against the live
API on two genuinely stuck sessions. Its wiring through
``archive_session`` is covered by unit tests rather than a live run.
imrichardwu pushed a commit to imrichardwu/airflow that referenced this pull request Sep 11, 2026
The API refuses to archive **or** delete a session while its status is
``running``, rejecting both with a 400. ``AnthropicAgentSessionOperator``
treats archiving as best-effort teardown on every failure path, so a
session that will not stop on its own is left behind with no way to
release it -- and it keeps accruing ``active_seconds``, which the SDK
describes as the duration the session's runtime cost is priced on.

Observed directly: two sessions halted by a $0.01 budget sat at status
``running`` for over 40 minutes with model spend frozen at the ceiling
while ``active_seconds`` kept climbing. ``archive`` and ``delete`` both
returned 400. Sending ``user.interrupt`` moved them to ``idle``
immediately, after which archiving succeeded.

``AnthropicHook.archive_session`` now interrupts and retries when the
first archive attempt fails, and ``interrupt_session`` exposes the event
on its own. The retry is bounded, so an unarchivable session still
surfaces its error rather than looping.

This is reachable well beyond budgets -- any session still working when a
task fails, times out, or is killed hits the same 400 -- but a budget halt
makes it routine, because that is a session which has stopped spending
without stopping.

The interrupt-then-archive sequence was verified by hand against the live
API on two genuinely stuck sessions. Its wiring through
``archive_session`` is covered by unit tests rather than a live run.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants