Skip to content

Recreate session on RunnerSessionInvalid from broker#4556

Merged
luketomlinson merged 5 commits into
mainfrom
luketomlinson-recreate-session-on-runner-session-inval
Jul 16, 2026
Merged

Recreate session on RunnerSessionInvalid from broker#4556
luketomlinson merged 5 commits into
mainfrom
luketomlinson-recreate-session-on-runner-session-inval

Conversation

@luketomlinson

@luketomlinson luketomlinson commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What

The service is changing so that when a runner polls (GET /message) or acknowledges with an invalid session, it returns HTTP 400 with a structured broker error body:

{"source":"actions-broker-listener","errorKind":"RunnerSessionInvalid","statusCode":400,"errorMessage":"Runner session is invalid"}

instead of a bare 403. Today a bare 403 makes the runner throw a fatal, misleading AccessDeniedException{ErrorCode=1} ("runner deprecated") and stop.

This PR makes the broker path behave like legacy Azure Pipelines did: on an expired/invalid session the runner recreates its session and keeps polling.

This brings it into parity with the MessageListener.cs

Changes

  1. BrokerErrorKind.cs — add the RunnerSessionInvalid constant.
  2. BrokerHttpClient.GetRunnerMessageAsync — map RunnerSessionInvalid to TaskAgentSessionExpiredException.
  3. BrokerMessageListener.GetNextMessageAsync — mirror legacy MessageListener: on TaskAgentSessionExpiredException (and when !SkipSessionRecover), recreate the session and continue polling instead of throwing a non-retryable error.

Added an L0 test asserting that when GetRunnerMessageAsync throws TaskAgentSessionExpiredException, the listener recreates the session and continues polling.

Rollout

Companion service PR: github/actions-broker-listener#2490. The runner change must roll out BEFORE the service enables its RejectInvalidSessions flag.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

The actions-broker-listener now returns HTTP 400 with a structured
broker error body of errorKind "RunnerSessionInvalid" when a runner
polls or acknowledges with an invalid session. Map that errorKind to
TaskAgentSessionExpiredException and, in BrokerMessageListener, recreate
the session and keep polling instead of failing with a misleading
'runner deprecated' error. This mirrors the legacy MessageListener
pipelines behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@luketomlinson
luketomlinson force-pushed the luketomlinson-recreate-session-on-runner-session-inval branch from 1280604 to bc7df92 Compare July 14, 2026 18:23
@luketomlinson
luketomlinson marked this pull request as ready for review July 15, 2026 19:22
@luketomlinson
luketomlinson requested a review from a team as a code owner July 15, 2026 19:22
@luketomlinson
luketomlinson requested review from Copilot July 15, 2026 19:22
@luketomlinson
luketomlinson requested a review from a team as a code owner July 15, 2026 19:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the broker polling path so that when the broker returns a structured RunnerSessionInvalid error (HTTP 400), the runner treats it like an expired session, recreates the session, and continues polling—matching the legacy/MessageListener behavior and avoiding misleading fatal “deprecated runner” failures.

Changes:

  • Add RunnerSessionInvalid to BrokerErrorKind.
  • Map RunnerSessionInvalid to TaskAgentSessionExpiredException in BrokerHttpClient.GetRunnerMessageAsync.
  • Update BrokerMessageListener.GetNextMessageAsync to recreate the session on TaskAgentSessionExpiredException (unless SkipSessionRecover), plus an L0 test validating the listener recovery behavior.
Show a summary per file
File Description
src/Test/L0/Listener/BrokerMessageListenerL0.cs Adds an L0 test asserting session recreation and continued polling after TaskAgentSessionExpiredException.
src/Sdk/WebApi/WebApi/BrokerHttpClient.cs Maps broker error kind RunnerSessionInvalid to TaskAgentSessionExpiredException for GET /message.
src/Sdk/RSWebApi/Contracts/BrokerErrorKind.cs Introduces the RunnerSessionInvalid broker error-kind constant.
src/Runner.Listener/BrokerMessageListener.cs Adds recovery logic to recreate the session when TaskAgentSessionExpiredException occurs during broker polling.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 4
  • Review effort level: Low

Comment on lines 126 to 130
case BrokerErrorKind.HostedRunnerDeprovisioned:
throw new HostedRunnerDeprovisionedException(brokerError.Message);
case BrokerErrorKind.RunnerSessionInvalid:
throw new TaskAgentSessionExpiredException(brokerError.Message);
default:
Comment on lines 126 to 130
case BrokerErrorKind.HostedRunnerDeprovisioned:
throw new HostedRunnerDeprovisionedException(brokerError.Message);
case BrokerErrorKind.RunnerSessionInvalid:
throw new TaskAgentSessionExpiredException(brokerError.Message);
default:
Comment on lines 126 to 130
case BrokerErrorKind.HostedRunnerDeprovisioned:
throw new HostedRunnerDeprovisionedException(brokerError.Message);
case BrokerErrorKind.RunnerSessionInvalid:
throw new TaskAgentSessionExpiredException(brokerError.Message);
default:
Comment thread src/Runner.Listener/BrokerMessageListener.cs Outdated
luketomlinson and others added 2 commits July 15, 2026 16:38
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Treat TaskAgentSessionExpiredException as non-retriable in
BrokerServer.ShouldRetryException so a RunnerSessionInvalid propagates
immediately to the recover branch instead of being retried 5x. Reword
the recover-branch comment to reference the runner session/service
rather than the DT agent session.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@@ -108,7 +108,7 @@ public Task ForceRefreshConnection(VssCredentials credentials)

public bool ShouldRetryException(Exception ex)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this layer is unnecessary, I'm not sure

@luketomlinson
luketomlinson merged commit c548023 into main Jul 16, 2026
12 checks passed
@luketomlinson
luketomlinson deleted the luketomlinson-recreate-session-on-runner-session-inval branch July 16, 2026 20:00
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.

3 participants