can1357/oh-my-pi · error · Error

Tool "${this.tool.name}" has pending provider safety checks

Error message

Tool "${this.tool.name}" has pending provider safety checks but no interactive UI is available.

What it means

The tool call requires provider-side safety checks (e.g. server-enforced confirmation) but the current runner has no interactive UI, and provider safety checks cannot be bypassed by any setting or yolo mode — they fail closed. The wrapper throws this error instead of executing the tool.

Source

Thrown at packages/coding-agent/src/extensibility/extensions/wrapper.ts:311

			const emitApprovalResolved = async (approved: boolean, reason?: string) => {
				if (!hasApprovalHandlers) return;
				await this.runner.emit({
					type: "tool_approval_resolved",
					sessionId,
					toolName: this.tool.name,
					toolCallId,
					approved,
					...(reason ? { reason } : {}),
				});
			};

			// Provider safety checks fail closed without an interactive prompt. Unlike
			// ordinary tier approval, no setting or yolo mode may bypass this gate.
			if (!this.runner.hasUI()) {
				const reason = "no interactive UI available";
				await emitApprovalResolved(false, reason);
				if (pendingSafetyChecks.length > 0) {
					throw new Error(
						`Tool "${this.tool.name}" has pending provider safety checks but no interactive UI is available.`,
					);
				}
				throw new Error(
					`Tool "${this.tool.name}" requires approval but no interactive UI available.\n` +
						`Options:\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`,
				);
			}

			const uiContext = this.runner.getUIContext();
			const basePrompt = formatApprovalPrompt(this.tool, resolvedArgs, approvalCheck.reason);
			const safetyPrompt =
				pendingSafetyChecks.length > 0
					? `${basePrompt}\nProvider safety checks:\n${safetyCheckLines(pendingSafetyChecks).join("\n")}`
					: basePrompt;

View on GitHub (pinned to 9690622007)

Solutions

  1. Run the tool call inside an interactive UI (TUI) so the safety-check prompt can be shown
  2. Route execution through an embedding that provides a UI to the runner (hasUI() true)
  3. If safety checks are already approved upstream, set context.providerSafetyApproved so the gate is skipped
  4. Restructure the workflow so the flagged tool call is not issued headlessly
Defensive patterns

Strategy: validation

Validate before calling

if (!runner.hasUI()) throw new Error('provider safety checks require an interactive UI; re-run in TUI');

Try / catch

try { await tool.execute(params); } catch (err) {
  if (err instanceof Error && err.message.includes('pending provider safety checks')) {
    // surface guidance: run interactively or pre-approve
  } else throw err;
}

Prevention

When it happens

Trigger: Running tool execution headlessly (SDK, RPC, non-TUI embedding) with a tool whose provider returned pending safety checks; this.runner.hasUI() returns false while pendingSafetyChecks.length > 0.

Common situations: Headless scripts or CI invoking the agent SDK; RPC mode without an attached UI; running in a piped/non-TTY environment where the interactive prompt cannot render.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/76cb6bc840023813. Report an issue: GitHub.