{"version":"2.1.289","anchor":"new-ui-client-fault-control-request-lets-the-desktop-report","canonical_anchor":"new-ui-client-fault-control-request-lets-the-desktop-report","heading":"Plugin UI failures are now caught, reported and recoverable","tier":"notice","area":"Plugin UI","scope":"individual","heads_up":false,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.289\/e\/new-ui-client-fault-control-request-lets-the-desktop-report","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.289","markdown":"### Plugin UI failures are now caught, reported and recoverable\n\nWhen a plugin's on-screen UI throws an error, Claude Code now catches it, draws its own UI instead and lets the plugin recover\n\n**Unclear.** It is not clear whether `ui.fault` handlers are behind a rollout switch or reachable only when the desktop app is the host.\n\n**What**\n\nPlugins can draw their own pieces of the Claude Code screen, such as a pane or content above the prompt. When that plugin-drawn UI fails, it is now contained and reported instead of breaking the screen or failing silently.\n\n- Error catching: a plugin answer or `Client` (a plugin-drawn view) that throws an error while being drawn is caught. Claude Code draws its own UI in its place and shows a message. This covers `Pane` and `AbovePrompt`. Previously a thrown error just removed the view and logged it.\n\n- Fault reports: the failure now records which phase failed (load, render or run) and is sent to a `raiseFault` handler. Failure notices are deduplicated and marked \"once\" or \"again\".\n\n- No redraw loop: a failed `Client` is not drawn again until its props or the place it is drawn change.\n\n- Resize limits: resize handling is rate-limited per view and per frame. Views caught in a re-measure loop are skipped and shown with the message \"drawn as last measured\".\n\n- Rejections: when a `Client`'s asynchronous handler fails (a rejection), it is reported through `host.fault` without ending the session.\n\n- Plugin recovery: the `ui_render` invalidate push, which tells a plugin to redraw, now also fires for a failed `Client` via `ui.fault`. Before, it covered state changes only.\n\n- Toasts: a toast stack (a pile of small pop-up notices) that throws while drawn is reported once as \"ui.toast: the toast stack threw while drawn\".\n\n- Desktop app: a new control request, `ui_client_fault`, with a `{handled}` response, lets the desktop app report a `Client` it drew that failed. The owning plugin's `ui.fault` chain then runs alone with the surface \"desktop\", so the plugin can draw a different view. The phase is load, render or run, and the reason is cut to 200 characters and cleaned.\n\n- `AbovePrompt` layout: the area's width now keeps a fixed margin of columns (`keptColumns`), and its holds-band report is skipped once the plugin has thrown.\n\n**Why**\n\nA broken plugin UI should no longer take down the screen or repeat the same error over and over. Plugin authors get a fault report and a chance to draw a fallback view, both in the terminal and in the desktop app.\n\n- Area: Plugin UI\n- Names: `ui_client_fault`\n- Tier: You'll notice\n- Useful: 4\/5\n- Signal: 4\/5\n- Scope: individual\n- Heads-up: no"}