mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-24 07:01:49 +00:00
fix(exec): skip gateway cwd injection for remote node host
When exec runs with host=node and no explicit cwd is provided, the gateway was injecting its own process.cwd() as the default working directory. In cross-platform setups (e.g. Linux gateway + Windows node), this gateway-local path does not exist on the node, causing "SYSTEM_RUN_DENIED: approval requires an existing canonical cwd". This change detects when no explicit workdir was provided (neither via the tool call params.workdir nor via agent defaults.cwd) and passes undefined instead of the gateway cwd. This lets the remote node use its own default working directory. Changes: - bash-tools.exec.ts: Track whether workdir was explicitly provided; when host=node and no explicit workdir, pass undefined instead of gateway process.cwd() - bash-tools.exec-host-node.ts: Accept workdir as string | undefined; only send cwd to system.run.prepare when defined - bash-tools.exec-approval-request.ts: Accept workdir as string | undefined in HostExecApprovalParams Fixes #58934 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
8aceaf5d0f
commit
3b3191ab3a
@@ -154,7 +154,7 @@ type HostExecApprovalParams = {
|
||||
commandArgv?: string[];
|
||||
systemRunPlan?: SystemRunApprovalPlan;
|
||||
env?: Record<string, string>;
|
||||
workdir: string;
|
||||
workdir: string | undefined;
|
||||
host: "gateway" | "node";
|
||||
nodeId?: string;
|
||||
security: ExecSecurity;
|
||||
@@ -245,3 +245,4 @@ export async function registerExecApprovalRequestForHostOrThrow(
|
||||
throw new Error(`Exec approval registration failed: ${String(err)}`, { cause: err });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import { listNodes, resolveNodeIdFromList } from "./tools/nodes-utils.js";
|
||||
|
||||
export type ExecuteNodeHostCommandParams = {
|
||||
command: string;
|
||||
workdir: string;
|
||||
workdir: string | undefined;
|
||||
env: Record<string, string>;
|
||||
requestedEnv?: Record<string, string>;
|
||||
requestedNode?: string;
|
||||
@@ -108,7 +108,7 @@ export async function executeNodeHostCommand(
|
||||
params: {
|
||||
command: argv,
|
||||
rawCommand: params.command,
|
||||
cwd: params.workdir,
|
||||
...(params.workdir != null ? { cwd: params.workdir } : {}),
|
||||
agentId: params.agentId,
|
||||
sessionKey: params.sessionKey,
|
||||
},
|
||||
@@ -121,7 +121,7 @@ export async function executeNodeHostCommand(
|
||||
}
|
||||
const runArgv = prepared.plan.argv;
|
||||
const runRawCommand = prepared.plan.commandText;
|
||||
const runCwd = prepared.plan.cwd ?? params.workdir;
|
||||
const runCwd = prepared.plan.cwd ?? params.workdir ?? undefined;
|
||||
const runAgentId = prepared.plan.agentId ?? params.agentId;
|
||||
const runSessionKey = prepared.plan.sessionKey ?? params.sessionKey;
|
||||
|
||||
@@ -453,3 +453,4 @@ export async function executeNodeHostCommand(
|
||||
} satisfies ExecToolDetails,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1343,8 +1343,9 @@ export function createExecTool(
|
||||
].join("\n"),
|
||||
);
|
||||
}
|
||||
const hasExplicitWorkdir = !!(params.workdir?.trim() || defaults?.cwd);
|
||||
const rawWorkdir = params.workdir?.trim() || defaults?.cwd || process.cwd();
|
||||
let workdir = rawWorkdir;
|
||||
let workdir: string | undefined = rawWorkdir;
|
||||
let containerWorkdir = sandbox?.containerWorkdir;
|
||||
if (sandbox) {
|
||||
const resolved = await resolveSandboxWorkdir({
|
||||
@@ -1354,10 +1355,17 @@ export function createExecTool(
|
||||
});
|
||||
workdir = resolved.hostWorkdir;
|
||||
containerWorkdir = resolved.containerWorkdir;
|
||||
} else if (host !== "node") {
|
||||
// Skip local workdir resolution for remote node execution: the remote node's
|
||||
// filesystem is not visible to the gateway, so resolveWorkdir() would incorrectly
|
||||
// fall back to the gateway's cwd. The node is responsible for validating its own cwd.
|
||||
} else if (host === "node") {
|
||||
// For remote node execution, only forward an explicit cwd provided by the
|
||||
// user or agent config. When no explicit cwd was given, the gateway's own
|
||||
// process.cwd() is meaningless on the remote node (especially cross-platform,
|
||||
// e.g. Linux gateway + Windows node) and would cause
|
||||
// "SYSTEM_RUN_DENIED: approval requires an existing canonical cwd".
|
||||
// Passing undefined lets the node use its own default working directory.
|
||||
if (!hasExplicitWorkdir) {
|
||||
workdir = undefined;
|
||||
}
|
||||
} else {
|
||||
workdir = resolveWorkdir(rawWorkdir, warnings);
|
||||
}
|
||||
rejectExecApprovalShellCommand(params.command);
|
||||
@@ -1627,3 +1635,4 @@ export function createExecTool(
|
||||
}
|
||||
|
||||
export const execTool = createExecTool();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user