can1357/oh-my-pi · error · ManualTriageConflict
ManualTriageConflict(delivery, existing.state)
Error message
ManualTriageConflict(delivery, existing.state)
What it means
ManualTriageConflict raised by enqueue_manual_triage when a previous triage event with the same delivery id is still active — i.e. its recorded state is "queued" or "running". The function refuses to enqueue a duplicate of an in-flight run.
Source
Thrown at python/robomp/src/manual_triage.py:100
"full_name": repo.full_name,
"default_branch": repo.default_branch,
"clone_url": repo.clone_url,
"private": repo.private,
},
}
async def enqueue_manual_triage(*, db: Database, github: GitHubBackend, repo_full: str, number: int) -> str:
"""Fetch the issue from GitHub and queue it for the worker pool.
Returns the delivery_id. A row may already exist from a previous manual
triage; inactive rows are replaced so the fresh payload (and reset attempt
counter) wins. Active rows are left intact.
"""
delivery = manual_delivery_id(repo_full, number)
existing = db.get_event(delivery)
if existing is not None and existing.state in ("queued", "running"):
raise ManualTriageConflict(delivery, existing.state)
payload = await build_issues_opened_payload(github, repo_full, number)
replaced = db.replace_event_if_state_in(
delivery_id=delivery,
event_type="issues",
repo=repo_full,
issue_key=issue_key(repo_full, number),
payload=payload,
state="queued",
allowed_existing_states=INACTIVE_EVENT_STATES,
)
if not replaced:
current = db.get_event(delivery)
state = current.state if current is not None else "active"
raise ManualTriageConflict(delivery, state)
return delivery
View on GitHub (pinned to 9690622007)
Solutions
- Wait for the existing run to reach a terminal state (done/failed/skipped) before re-triggering
- Use await_terminal_state(delivery_id) to wait, or poll the event state
- If a stale run is stuck, reset/force-close the existing event row, then re-enqueue
Example fix
// before: unguarded re-trigger
await enqueue_manual_triage(github, db, repo, num)
// after: wait out any active run first
try:
await await_terminal_state(db, delivery_id)
except ManualTriageTimeout:
pass
await enqueue_manual_triage(github, db, repo, num) Defensive patterns
Strategy: try-catch
Validate before calling
existing = db.get_event(manual_delivery_id(repo_full, number))
if existing is not None and existing.state in ("queued", "running"):
raise RuntimeError(f"triage already {existing.state} for {repo_full}#{number}") Try / catch
try:
delivery = await enqueue_manual_triage(github, db, repo_full, number)
except ManualTriageConflict as e:
log.info("triage already %s; reusing delivery %s", e.args, e.args[0])
delivery = e.args[0] Prevention
- Disable/dedupe the trigger button while a run is active
- Track active deliveries per repo#issue in the caller
- Wait for terminal state before allowing re-trigger
When it happens
Trigger: Calling enqueue_manual_triage (via _go or api_trigger) twice for the same repo#issue before the first run finishes.
Common situations: Double-clicking the triage trigger in the dashboard, re-running an API trigger while a prior manual triage is still executing.
Related errors
- run ${jobName} is already running
- ManualTriageConflict(delivery, state)
- {str(exc)} (ManualTriageConflict)
- delivery {target} is {event.state}; only inactive events can
- native spelling thread stopped
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/826b06adc8cce78c.
Report an issue: GitHub.