{"record":{"id":"0ad2e699363ab034","repo":"can1357/oh-my-pi","slug":"omp-agent-error-stopreason-error-error-msg","errorCode":null,"errorMessage":"omp agent error (stopReason=error): {error_msg}","messagePattern":"omp agent error \\(stopReason=error\\): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/robomp/src/worker.py","lineNumber":778,"sourceCode":"                turn = _drive_turn(\n                    client,\n                    prompt,\n                    task_kind=task_kind,\n                    inputs=inputs,\n                    bindings=bindings,\n                    tools_called=tools_called,\n                )\n                if turn is None:\n                    return None\n            finally:\n                hard_timer.cancel()\n            if hard_timeout_fired.is_set():\n                raise TimeoutError(\"omp task exceeded hard timeout\")\n            if turn is not None and turn.assistant_message is not None:\n                stop_reason = turn.assistant_message.get(\"stopReason\")\n                if stop_reason == \"error\":\n                    error_msg = turn.assistant_message.get(\"errorMessage\") or \"model returned error\"\n                    raise RuntimeError(f\"omp agent error (stopReason=error): {error_msg}\")\n            log.info(\n                \"rpc_done\",\n                extra={\n                    \"issue\": bindings.issue_key,\n                    \"task\": task_kind,\n                    \"messages\": len(turn.messages),\n                    \"events\": len(turn.events),\n                },\n            )\n            return turn.assistant_text\n        finally:\n            unregister_cancel_hook()\n\n\nasync def run_task(\n    *,\n    task_kind: str,\n    inputs: TaskInputs,","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/worker.py#L760-L796","documentation":"run_task's RPC driver raises RuntimeError('omp agent error (stopReason=error): {error_msg}') when the omp --mode rpc turn finishes normally but its assistant_message reports stopReason 'error'. The message forwards the underlying errorMessage from the agent (or 'model returned error' when absent), meaning the agent subprocess ended its turn with an error rather than a result.","triggerScenarios":"The omp subprocess returns a turn whose assistant_message.stopReason == 'error' — model/provider API failures (auth, quota, rate limit), the agent hitting a fatal internal error, invalid model configuration, or the gateway rejecting the request mid-session.","commonSituations":"Expired/invalid provider credentials in models.yml or env; provider outage or 429/5xx from the LLM gateway; ROBOMP_MODEL naming a model the provider rejects; context overflow on long resumed sessions; provider returns an empty/error completion that omp surfaces as stopReason=error.","solutions":["Read the appended {error_msg} in events.last_error — it carries the underlying omp errorMessage with the provider's reason.","Verify model/provider credentials and that ROBOMP_MODEL (and ROBOMP_PROVIDER/ROBOMP_THINKING) name a valid, affordable model for the account.","Check the LLM gateway health; transient 429/5xx outages just need a retry (POST /api/trigger with the delivery_id).","If it is context overflow on a resumed session, use robomp cleanup owner/repo#N or trigger a fresh triage to start a new session.","Reproduce locally with the same omp command (omp --mode rpc) to get the full provider error outside the orchestrator."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify provider config before dispatching\nif (!process.env.ROBOMP_MODEL) throw new Error('ROBOMP_MODEL unset');\n// and validate the gateway answers:\nconst ok = (await fetch(`${gatewayUrl}/healthz`)).ok;","typeGuard":"function isAgentErrorTurn(msg: Record<string, unknown> | null | undefined): boolean {\n  return !!msg && msg.stopReason === 'error';\n}","tryCatchPattern":"try {\n  result = await runTask(...);\n} catch (e) {\n  if (e instanceof RuntimeError && e.message.includes('omp agent error')) {\n    const detail = e.message.split(': ').slice(1).join(': ');\n    log.error('omp agent failed', { detail });\n    if (/429|rate limit/i.test(detail)) await backoffAndRetry(deliveryId);\n  } else throw e;\n}","preventionTips":["Keep provider credentials and ROBOMP_MODEL valid and test them before deploy.","Monitor the gateway for outages/429s; add backoff on retry.","Run `robomp cleanup owner/repo#N` for long resumed sessions hitting context limits.","Surface events.last_error to operators so the underlying errorMessage is readable.","Pin a fallback model/pool for task kinds prone to provider rejections."],"tags":["llm","provider-error","omp","rpc"],"backgroundTag":"llm-provider-request-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}