{"record":{"id":"fd893e06e6be24e8","repo":"Hmbown/CodeWhale","slug":"foreground-denied","errorCode":"foreground_denied","errorMessage":"the user denied shared-desktop (foreground) control on this computer — continue with open_application activate:false (background control) or ask them to reconsider.","messagePattern":"the user denied shared-desktop \\(foreground\\) control on this computer — continue with open_application activate:false \\(background control\\) or ask them to reconsider\\.","errorType":"error_code","errorClass":"ServerError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/mcp/server.mjs","lineNumber":596,"sourceCode":"    if (verdict.state === \"denied\") {\n      throw new ServerError(\"app_denied\",\n        `the user denied access to ${desc} on this computer — do not work around it; only they can change it (consent {action:\"revoke\"}).`,\n        { app: known });\n    }\n    if (verdict.state === \"undecided\") {\n      throw new ServerError(\"consent_required\",\n        `Codewhale needs the user's permission to use ${desc} on this computer — ask them, then record their answer with consent {action:\"allow\"|\"deny\", app:\"${arg}\"}.`,\n        { app: known });\n    }\n    grant = { ref: known, persisted: verdict.persisted === true };\n  }\n  // Taking the shared pointer/focus is a second, separate consent: the first\n  // activate:true is the moment the agent stops being background — on every\n  // platform, not just macOS.\n  if (name === \"open_application\" && args.activate === true) {\n    const fg = consent.foregroundDecision(computer.id);\n    if (fg.state === \"denied\") {\n      throw new ServerError(\"foreground_denied\",\n        `the user denied shared-desktop (foreground) control on this computer — continue with open_application activate:false (background control) or ask them to reconsider.`,\n        { scope: \"foreground\" });\n    }\n    if (fg.state === \"undecided\") {\n      throw new ServerError(\"foreground_consent_required\",\n        `open_application activate:true would take this computer's shared pointer and focus — ask the user, then record their answer with consent {action:\"allow\"|\"deny\", scope:\"foreground\"}. Background control (activate:false) needs no such consent.`,\n        { scope: \"foreground\" });\n    }\n  }\n  return grant ? { grant } : null;\n}\n\n// ---------- tool dispatch ----------\nasync function callTool(params) {\n  const requested = params.name;\n  if (!TOOL_NAMES.has(requested)) {\n    return { content: [{ type: \"text\", text: JSON.stringify({ ok: false, error: { code: \"unknown_tool\", message: `unknown tool \"${requested}\"` } }) }], isError: true };\n  }","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/mcp/server.mjs#L578-L614","documentation":"Thrown by consentCheck() when open_application is called with activate:true but the user has recorded a deny decision for shared-desktop (foreground) control. Taking the shared pointer/focus is a second, separate consent from per-app access on every platform. The error offers the supported alternative: background control with activate:false, or asking the user to reconsider.","triggerScenarios":"open_application with args.activate === true while consent.foregroundDecision(computer.id).state === \"denied\".","commonSituations":"User denied foreground control earlier in the session or via a persisted decision; an agent habitually passes activate:true and hits the deny on every launch attempt.","solutions":["Re-call open_application with activate:false for background control.","Ask the user to reconsider; if they agree, record it with consent {action:\"allow\", scope:\"foreground\"}.","If the deny was persisted by mistake, revoke it with consent {action:\"revoke\", scope:\"foreground\"}."],"exampleFix":"// before\nawait callTool({ name: \"open_application\", arguments: { name: \"Firefox\", activate: true } }); // throws foreground_denied\n\n// after: background control needs no foreground consent\nawait callTool({ name: \"open_application\", arguments: { name: \"Firefox\", activate: false } });","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await callTool({ name: \"open_application\", arguments: { ...args, activate: true } });\n} catch (e) {\n  if (e.code === \"foreground_denied\") {\n    // fall back to background control, which requires no foreground consent\n    return await callTool({ name: \"open_application\", arguments: { ...args, activate: false } });\n  }\n  throw e;\n}","preventionTips":["Default to activate:false unless foreground focus is genuinely required.","Remember a foreground deny for the session and never send activate:true again.","On foreground_denied, offer the user a one-step way to change their decision."],"tags":["consent","foreground","computer-use","mcp"],"backgroundTag":"permission-denied","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}