Skip to content

fix: stop agents crashing on transport errors and message panics - #195

Merged
paullatzelsperger merged 3 commits into
mainfrom
fix/nil_response_on_transport_errors
Oct 30, 2026
Merged

paullatzelsperger merged 3 commits into
mainfrom
fix/nil_response_on_transport_errors

Conversation

@paullatzelsperger

Copy link
Copy Markdown
Contributor

What this PR changes

When Siglet, IdentityHub or the control plane were unreachable, agents dereferenced a nil *http.Response and the process exited. The message was never acked, so it was redelivered after the restart and the agent crash-looped while the downstream was down. This PR fixes that, one commit per change:

  • Check the transport error before touching the response. The Siglet, IdentityHub and control plane clients now return the error instead of panicking. This also fixes the control plane client closing the body before reading it, which left error details empty.
  • One shared, nil-safe helper. httpx.DrainAndClose replaces the five per-client copies of the drain-and-close logic.
  • Recover per message. RetriableMessageProcessor.ProcessMessage and the PM activity executor recover from a panic, log it with the stack trace and terminate the message, so a single message can't take down an agent or PM.

Notes for reviewers

  • A panicking message is terminated rather than NAKed, because the panic usually repeats on redelivery. The orchestration behind a terminated activity message stays stuck instead of being marked errored. Dead-lettering is a separate change.
  • The PM KV watcher callback (a core-NATS subscription) is not covered by the recover.

🤖 Generated with Claude Code

paullatzelsperger and others added 3 commits October 30, 2026 13:18
The Siglet, IdentityHub and control plane clients deferred draining the
response body before checking the error returned by http.Client.Do. On a
transport error the response is nil, so the agent panicked instead of
returning the error.

Check the error first and only then defer draining the body. This also
fixes the control plane client closing the body before reading it, which
left error details empty.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e helper

Five agent HTTP clients each carried their own copy of the drain-and-close
logic. Replace them with httpx.DrainAndClose, which also tolerates a nil
response or body so a misplaced call can no longer panic.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A panic in a message dispatcher or activity processor ran in a goroutine
without recover, so it took down the whole process. The message was never
acked, so it was redelivered after the restart and the agent crash-looped.

Recover per message in both RetriableMessageProcessor.ProcessMessage and
the activity executor, log the panic with its stack trace, and terminate
the message so it is not redelivered.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@paullatzelsperger
paullatzelsperger requested review from jimmarino and wolf4ood and removed request for wolf4ood October 30, 2026 12:26
@paullatzelsperger
paullatzelsperger merged commit 65cc172 into main Oct 30, 2026
3 checks passed
@paullatzelsperger
paullatzelsperger deleted the fix/nil_response_on_transport_errors branch October 30, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants