Skip to content

fix(skills): give a crashed Chromium app a recovery path that exists - #703

Draft
latekvo wants to merge 1 commit into
mainfrom
fix/chromium-debugger-recovery
Draft

fix(skills): give a crashed Chromium app a recovery path that exists#703
latekvo wants to merge 1 commit into
mainfrom
fix/chromium-debugger-recovery

Conversation

@latekvo

@latekvo latekvo commented Aug 3, 2026

Copy link
Copy Markdown
Member

Found while reviewing #610 and set aside as out of scope: it is present on main today and #610 does not change the remedy text.

The defect

references/failure-scenarios.md, the "Was connected, then tool fails" row, is the skill's only answer to the app died. It sends every reader to restart-app. On a Chromium (CDP) target restart-app has no chromium capability (packages/tool-server/src/tools/restart-app/index.ts:41-46), so the call never reaches a device:

POST /tools/restart-app {"udid":"chromium-cdp-19722","bundleId":"com.example.app"}
-> HTTP 400
{"error":"Tool 'restart-app' is not supported on chromium app (no chromium support declared)."}

The row's precondition is reachable there. With a real Electron app booted via boot-device and then killed, every Chromium-capable debugger tool fails with the row's trigger:

{"error":"[Tool:debugger-evaluate] Service dependency failed: [ChromiumCdp:chromium-cdp-38329]
  Chromium CDP discovery: GET http://127.0.0.1:38329/json/version could not connect.
  Is the app running with --remote-debugging-port? — caused by: connect ECONNREFUSED"}
-> HTTP 500

So the skill markets Chromium as a first-class target (SKILL.md:3, :12), gets a Chromium user into this state, and then offers a recovery that is rejected before it runs. launch-app is not a way out either - it carries chromium capability but needs the live renderer, and fails with the same ECONNREFUSED.

The fix

One sentence on the row naming the relaunch that does work, plus scope tags on the two tables that list restart-app with no platform qualifier. SKILL.md:12 already uses "reject Chromium at the capability gate" and argent-device-interact already uses the bold platform + "instead" shape, so the wording follows what is there.

Verification

Full recovery run against a real Electron app, following the new wording end to end:

step result
session healthy debugger-evaluate -> "result":"probe-v1"
kill the app -
debugger tool fails (row precondition) HTTP 500 ECONNREFUSED
row's current remedy: restart-app HTTP 400 capability gate
new wording step 1: boot-device + electronAppPath {"platform":"chromium","id":"chromium-cdp-36313","booted":true}
new wording step 2: debugger-connect with the new id HTTP 200 "connected":true
session restored debugger-evaluate -> "result":"probe-v1", HTTP 200

The browser branch was verified separately (kill the CDP endpoint, relaunch on the same port, reconnect with the same chromium-cdp-<port> id). The id only changes when the port does, which is why the wording says to take it from boot-device / list-devices: boot-device picks a free port per call and never reuses the dead one unless electronPort is passed.

node scripts/grade-skills.mjs -> all 15 skills 10.0/10. Prettier clean (the table realignment in the diff is prettier widening the columns).

Not changed

  • "App not connected" (line 9) also names restart-app, but its trigger is the verbatim Metro string Metro at port 8081 has no CDP targets, which the Chromium path never emits - Chromium reports Chromium CDP on port N reported no page targets instead. Every platform that can emit the Metro string is covered by restart-app's capability, Vega included.
  • fix(debugger): cut debugger tool fail rate — structured not-connected results, classified CDP failures, narrow recovery #610 adds two more rows with the same prescription (stale connection, CDP request timed out). They will want the same qualifier once that branch lands; this PR deliberately does not touch rows that only exist there.

The "Was connected, then tool fails" row in the metro-debugger skill's
failure-scenarios reference sends every reader to `restart-app`. On a
Chromium (CDP) target that tool is rejected at the capability gate, so the
one recovery the skill offers for a dead app cannot run there:

    POST /tools/restart-app {"udid":"chromium-cdp-19722", ...}
    -> HTTP 400
    {"error":"Tool 'restart-app' is not supported on chromium app
      (no chromium support declared)."}

The row's precondition is reachable on Chromium: with the Electron process
killed, debugger-status, -connect, -evaluate and -log-registry all fail with
a CDP connect error, which is exactly the row's trigger. `launch-app`
carries chromium capability but needs the live renderer, so it fails the
same way.

The row now names the relaunch that does work, and the two tables that list
`restart-app` without scope say which platforms it covers.
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.

1 participant