From e3d74619bc9d2cf6d93bc5cb19e35d318784bf6a Mon Sep 17 00:00:00 2001 From: justinhuangcode Date: Mon, 23 Feb 2026 17:26:04 +0000 Subject: [PATCH] fix(gateway): include platform and reason in node command rejection error The generic "node command not allowed" error gives no indication of why the command was rejected, making it hard to diagnose issues (e.g. running `nodes notify` against a Linux node that does not declare `system.notify`). Include the rejection reason and node platform in the error message so callers can tell whether the command is not supported by the node, not in the platform allowlist, or the node did not advertise its capabilities. Fixes #24616 Co-Authored-By: Claude Opus 4.6 --- src/gateway/server-methods/browser.ts | 4 +++- src/gateway/server-methods/nodes.ts | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/gateway/server-methods/browser.ts b/src/gateway/server-methods/browser.ts index fb042ad696c..c83ad947570 100644 --- a/src/gateway/server-methods/browser.ts +++ b/src/gateway/server-methods/browser.ts @@ -169,10 +169,12 @@ export const browserHandlers: GatewayRequestHandlers = { allowlist, }); if (!allowed.ok) { + const platform = nodeTarget.platform ?? "unknown"; + const hint = `node command not allowed: ${allowed.reason} (platform: ${platform}, command: browser.proxy)`; respond( false, undefined, - errorShape(ErrorCodes.INVALID_REQUEST, "node command not allowed", { + errorShape(ErrorCodes.INVALID_REQUEST, hint, { details: { reason: allowed.reason, command: "browser.proxy" }, }), ); diff --git a/src/gateway/server-methods/nodes.ts b/src/gateway/server-methods/nodes.ts index 9bb27049685..4f076abd59c 100644 --- a/src/gateway/server-methods/nodes.ts +++ b/src/gateway/server-methods/nodes.ts @@ -687,10 +687,11 @@ export const nodeHandlers: GatewayRequestHandlers = { allowlist, }); if (!allowed.ok) { + const hint = buildNodeCommandRejectionHint(allowed.reason, command, nodeSession); respond( false, undefined, - errorShape(ErrorCodes.INVALID_REQUEST, "node command not allowed", { + errorShape(ErrorCodes.INVALID_REQUEST, hint, { details: { reason: allowed.reason, command }, }), ); @@ -784,3 +785,21 @@ export const nodeHandlers: GatewayRequestHandlers = { }); }, }; + +function buildNodeCommandRejectionHint( + reason: string, + command: string, + node: { platform?: string } | undefined, +): string { + const platform = node?.platform ?? "unknown"; + if (reason === "command not declared by node") { + return `node command not allowed: the node (platform: ${platform}) does not support "${command}"`; + } + if (reason === "command not allowlisted") { + return `node command not allowed: "${command}" is not in the allowlist for platform "${platform}"`; + } + if (reason === "node did not declare commands") { + return `node command not allowed: the node did not declare any supported commands`; + } + return `node command not allowed: ${reason}`; +}