View on GitHub

Agentic Workflows — Field Guide

A field guide to using GitHub Workflows and Agentic Workflows

← Previous: Operating Within a Fork Table of Contents Next: Authorization, Roles, and Read-Only Contributors →

Concurrency and Race Conditions

GitHub’s concurrency model1:

concurrency:
  group: $-$
  cancel-in-progress: true

The “non-matching cancels matching” race

Concrete scenario: workflow triage.md has slash_command: triage and concurrency.group: triage-$ with cancel-in-progress: true.

T+0  s: User comments "/triage" on issue #42 → run A starts; pre-activation matches; agent job begins.
T+10 s: Same user adds a clarifying comment "Actually, I meant the 1.x version." (no slash command).
        → issue_comment event fires; run B is queued.
        → Concurrency group "triage-42" already has run A in-progress → A is canceled.
        → Run B's pre-activation runs, sees no slash command, exits skip.
        → Net result: the triage agent for /triage was killed mid-run by an unrelated comment.

This is the non-matching-cancels-matching pathology. Mitigations:

  1. Narrow slash_command events: so the workflow doesn’t subscribe to events that can’t possibly match — e.g., events: [issue_comment] when the slash command will only ever appear in comments.
  2. Make the concurrency group depend on the activation outcome. This is hard — concurrency: is evaluated before the job starts and cannot reference job outputs. The practical workaround is to make the group narrower (e.g., include $) so unrelated events don’t share the group.
  3. Don’t set cancel-in-progress: true for slash-command workflows; let them queue.
  4. Make outputs idempotent (use deterministic comment markers, upsert labels, check for existing PRs) so a re-run produces the same end state.

The pre-cancellation race

Even without conflicting groups, steps that have already started will complete before cancellation lands. This means:

Concurrency is not a substitute for idempotency.


← Previous: Operating Within a Fork Table of Contents Next: Authorization, Roles, and Read-Only Contributors →
  1. GitHub Docs, Using concurrency