{"record":{"id":"946455510da797b0","repo":"can1357/oh-my-pi","slug":"tool-this-tool-name-requires-approval-but-no","errorCode":null,"errorMessage":"Tool \"${this.tool.name}\" requires approval but no interactive UI available.\nOptions:\n  1. Set tools.approvalMode: yolo in /settings\n  2. Add tools.approval.${this.tool.name}: allow to config\n  3. Use an interactive UI to approve the tool call","messagePattern":"Tool \"(.+?)\" requires approval but no interactive UI available\\.\nOptions:\n  1\\. Set tools\\.approvalMode: yolo in /settings\n  2\\. Add tools\\.approval\\.(.+?): allow to config\n  3\\. Use an interactive UI to approve the tool call","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/extensions/wrapper.ts","lineNumber":315,"sourceCode":"\t\t\t\t\tsessionId,\n\t\t\t\t\ttoolName: this.tool.name,\n\t\t\t\t\ttoolCallId,\n\t\t\t\t\tapproved,\n\t\t\t\t\t...(reason ? { reason } : {}),\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t// Provider safety checks fail closed without an interactive prompt. Unlike\n\t\t\t// ordinary tier approval, no setting or yolo mode may bypass this gate.\n\t\t\tif (!this.runner.hasUI()) {\n\t\t\t\tconst reason = \"no interactive UI available\";\n\t\t\t\tawait emitApprovalResolved(false, reason);\n\t\t\t\tif (pendingSafetyChecks.length > 0) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Tool \"${this.tool.name}\" has pending provider safety checks but no interactive UI is available.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tool \"${this.tool.name}\" requires approval but no interactive UI available.\\n` +\n\t\t\t\t\t\t`Options:\\n` +\n\t\t\t\t\t\t`  1. Set tools.approvalMode: yolo in /settings\\n` +\n\t\t\t\t\t\t`  2. Add tools.approval.${this.tool.name}: allow to config\\n` +\n\t\t\t\t\t\t`  3. Use an interactive UI to approve the tool call`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst uiContext = this.runner.getUIContext();\n\t\t\tconst basePrompt = formatApprovalPrompt(this.tool, resolvedArgs, approvalCheck.reason);\n\t\t\tconst safetyPrompt =\n\t\t\t\tpendingSafetyChecks.length > 0\n\t\t\t\t\t? `${basePrompt}\\nProvider safety checks:\\n${safetyCheckLines(pendingSafetyChecks).join(\"\\n\")}`\n\t\t\t\t\t: basePrompt;\n\t\t\tlet choice: string | undefined;\n\t\t\ttry {\n\t\t\t\tchoice = await uiContext.select(safetyPrompt, [\"Approve\", \"Deny\"]);\n\t\t\t} catch (err) {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/extensions/wrapper.ts#L297-L333","documentation":"The tool requires tier approval, but no interactive UI is available to prompt the user, so execution is refused. Unlike provider safety checks, ordinary approval CAN be satisfied via configuration (yolo mode or an explicit allow rule), which is what the error message suggests.","triggerScenarios":"Executing a tool whose resolved approval policy is not 'allow' while this.runner.hasUI() is false and no provider safety checks are pending; headless/SDK/RPC execution of tools that normally prompt.","commonSituations":"Headless scripts calling approval-gated tools (bash, edit) without UI; CI pipelines; misconfigured environments where approvalMode or per-tool allow rules were not set.","solutions":["Set tools.approvalMode: yolo in settings to auto-approve all tools in trusted environments","Add an allow rule for this specific tool: tools.approval.<toolName>: allow in config","Run via an interactive UI so the approval prompt can be answered","Programmatically supply an approval resolver in the SDK embedding"],"exampleFix":"// config (JSON)\n// before\n\"tools\": {}\n// after\n\"tools\": { \"approval\": { \"bash\": \"allow\" } }","handlingStrategy":"validation","validationCode":"const needsApproval = resolveApprovalPolicy(toolName) !== 'allow';\nif (needsApproval && !runner.hasUI()) throw new Error(`tool ${toolName} will fail headless: pre-approve via tools.approval config`);","typeGuard":null,"tryCatchPattern":"try { await tool.execute(params); } catch (err) {\n  if (err instanceof Error && err.message.includes('requires approval but no interactive UI')) {\n    // pre-approve via config or switch to interactive mode and retry\n  } else throw err;\n}","preventionTips":["Set tools.approvalMode: yolo (trusted envs) or per-tool tools.approval allow rules before headless runs","Validate the approval config in CI for headless pipelines","Check hasUI() before executing approval-gated tools","Prefer narrowly scoped allow rules over yolo"],"tags":["approval-gate","headless","configuration","ui"],"backgroundTag":"approval-required-no-ui","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}