n8n-io/n8n · info · Error
GATEWAY_CONFIRMATION_REQUIRED::${JSON.stringify({ toolGroup:
Error message
GATEWAY_CONFIRMATION_REQUIRED::${JSON.stringify({ toolGroup: resource.toolGroup, resource: resource.resource, description: resource.description, options: INSTANCE_RESOURCE_DECISION_KEYS })} What it means
This is a structured control-flow signal, not a real error. Thrown by checkPermissions() when config.permissionConfirmation === 'instance' and no pre-supplied decision was passed. The message starts with 'GATEWAY_CONFIRMATION_REQUIRED::' followed by a JSON payload describing the resource, its description, and the available decision options. It is designed to be caught by the gateway message handler and forwarded to the n8n UI for interactive user confirmation.
Source
Thrown at packages/@n8n/computer-use/src/gateway-client.ts:513
const { session, confirmResourceAccess, config } = this.options;
for (const resource of resources) {
const rule = session.check(resource.toolGroup, resource.resource);
if (rule === 'deny') {
throw new Error(
`User permanently denied access to ${resource.toolGroup}: ${resource.resource}`,
);
}
if (rule === 'allow') continue;
let resolvedDecision: ResourceDecision;
if (decision && config.permissionConfirmation === 'instance') {
resolvedDecision = decision;
} else if (config.permissionConfirmation === 'instance') {
throw new Error(
`${GATEWAY_CONFIRMATION_REQUIRED_PREFIX}${JSON.stringify({
toolGroup: resource.toolGroup,
resource: resource.resource,
description: resource.description,
options: INSTANCE_RESOURCE_DECISION_KEYS,
})}`,
);
} else {
resolvedDecision = await confirmResourceAccess(resource);
}
switch (resolvedDecision) {
case 'allowOnce':
break;
case 'allowForSession':
session.allowForSession(resource.toolGroup, resource.resource);
break;
case 'alwaysAllow':View on GitHub (pinned to 5ac6606e81)
Solutions
- Catch errors whose message starts with GATEWAY_CONFIRMATION_REQUIRED_PREFIX
- Parse the JSON payload after the prefix to get toolGroup, resource, description, and options
- Forward the confirmation request to the n8n instance UI via the gateway response channel
- Resume the tool call with the user's ResourceDecision once they respond
Example fix
// before (unhandled):
try { await gateway.callTool(name, args); }
catch (e) { throw e; // loses the confirmation signal }
// after:
try {
await gateway.callTool(name, args);
} catch (e) {
if (e.message?.startsWith('GATEWAY_CONFIRMATION_REQUIRED::')) {
const payload = JSON.parse(e.message.slice('GATEWAY_CONFIRMATION_REQUIRED::'.length));
await sendConfirmationToUI(payload);
// resume with the user's decision
} else throw e;
} Defensive patterns
Strategy: try-catch
Type guard
const GATEWAY_CONFIRMATION_REQUIRED_PREFIX = 'GATEWAY_CONFIRMATION_REQUIRED::';
function isConfirmationRequired(e: unknown): e is Error & { payload: object } {
return e instanceof Error && e.message.startsWith(GATEWAY_CONFIRMATION_REQUIRED_PREFIX);
}
function parseConfirmationPayload(e: Error): {
toolGroup: string; resource: string; description: string; options: string[];
} {
return JSON.parse(e.message.slice(GATEWAY_CONFIRMATION_REQUIRED_PREFIX.length));
} Try / catch
try {
return await gatewayClient.callTool(name, args);
} catch (e) {
if (e instanceof Error && e.message.startsWith('GATEWAY_CONFIRMATION_REQUIRED::')) {
const payload = JSON.parse(e.message.slice('GATEWAY_CONFIRMATION_REQUIRED::'.length));
// Forward to the n8n instance UI for user confirmation
const decision = await forwardToInstanceUI(payload);
// Retry with the user's decision
return await gatewayClient.callTool(name, args, decision);
}
throw e;
} Prevention
- Always handle GATEWAY_CONFIRMATION_REQUIRED as a control-flow signal, not an error
- When calling from instance mode, supply the decision parameter if available to avoid the round-trip
- Parse the JSON payload to extract toolGroup, resource, and available decision options for the UI
When it happens
Trigger: A tool is invoked in instance-confirmation mode, the resource is neither pre-approved nor pre-denied in the session, and no decision was included in the gateway tool-call message. This is the normal first-access flow for any new resource.
Common situations: First access to a new file path, browser domain, or shell command in instance-confirmation mode — the user has not yet seen a confirmation prompt for this resource.
Related errors
- User permanently denied access to ${resource.toolGroup}: ${r
- User denied access to ${resource.toolGroup}: ${resource.reso
- Gateway rejected token: ${status} ${body}
- Failed to upload capabilities: ${response.status} ${text}
- Credential creation failed: ${res.status} ${text}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/d5be744da277e8f4.
Report an issue: GitHub.