Context
When an upstream task queue (e.g. an issue-watcher) has a race condition, the taskrunner can end up executing two tasks for the same GitHub issue concurrently or sequentially. This results in duplicate PRs and merge conflicts.
Found in production: Stackbilt-dev/aegis#162
Proposed Enhancement
Before starting a task, the taskrunner should check the queue for other tasks with the same github_issue_repo + github_issue_number that are already running or completed. If found, skip the duplicate and mark it as cancelled with a reason.
This is a defense-in-depth measure — the upstream queue should prevent duplicates, but the runner should also guard against them.
Implementation Sketch
In execute_task(), after fetching the task but before starting Claude Code:
# Check for duplicate issue tasks
if [[ -n "$github_issue_number" && -n "$github_issue_repo" ]]; then
existing=$(curl -s "${API_BASE}/api/cc-tasks?github_issue_repo=${github_issue_repo}&github_issue_number=${github_issue_number}&status=completed,running" | jq '.tasks | length')
if [[ "$existing" -gt 0 ]]; then
log "Skipping duplicate: another task for ${github_issue_repo}#${github_issue_number} already exists"
# Cancel this task
curl -s -X POST "${API_BASE}/api/cc-tasks/${task_id}/cancel" ...
return 0
fi
fi
This requires the task queue API to support filtering by github_issue_repo and github_issue_number, which the AEGIS implementation already does.
Context
When an upstream task queue (e.g. an issue-watcher) has a race condition, the taskrunner can end up executing two tasks for the same GitHub issue concurrently or sequentially. This results in duplicate PRs and merge conflicts.
Found in production: Stackbilt-dev/aegis#162
Proposed Enhancement
Before starting a task, the taskrunner should check the queue for other tasks with the same
github_issue_repo+github_issue_numberthat are alreadyrunningorcompleted. If found, skip the duplicate and mark it as cancelled with a reason.This is a defense-in-depth measure — the upstream queue should prevent duplicates, but the runner should also guard against them.
Implementation Sketch
In
execute_task(), after fetching the task but before starting Claude Code:This requires the task queue API to support filtering by
github_issue_repoandgithub_issue_number, which the AEGIS implementation already does.