You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RemoteAgent.run rejects successful API responses whose body omits the error field (result.error !== null trap) #2637
RemoteAgent.run (the hosted/remote-agent execution path of @mcp-use/agent) treats a successful HTTP 200 response as a failure whenever the JSON body does not contain an explicit error: null key. The guard at libraries/typescript/packages/agent/src/agents/remote.ts:347 reads:
if(result.status==="error"||result.error!==null){
For a success body like {"result": "The answer"} the error key is simply absent, so result.error is undefined, and undefined !== null is true — the success response is treated as a failure and run() throws Remote agent execution failed: [object Object] (the message comes from the interpolation at remote.ts:348, result.error ?? String(result)). Only bodies that literally contain error: null pass through as successes.
To Reproduce
Steps to reproduce the behavior:
Save the test below as libraries/typescript/packages/agent/tests/repro-remote-error-field.test.ts (fetch is stubbed — no network is contacted).
Run cd libraries/typescript/packages/agent && npx vitest run tests/repro-remote-error-field.test.ts.
See cases A and B — plain success bodies — being rejected.
import{describe,it}from"vitest";import{RemoteAgent}from"../src/agents/remote.js";/** Install a fetch stub that replays the given JSON bodies with HTTP 200. */functionstubFetch(bodies: unknown[]){leti=0;(globalThisasany).fetch=async()=>{constbody=bodies[Math.min(i,bodies.length-1)];i++;return{ok: true,status: 200,json: async()=>body,text: async()=>JSON.stringify(body),};};}functionmakeAgent(): RemoteAgent{returnnewRemoteAgent({agentId: "agent-1",apiKey: "test-key",baseUrl: "http://127.0.0.1:1",// never contacted; fetch is stubbed});}describe("RemoteAgent handling of successful responses",()=>{it("response body {result: string} (no error field)",async()=>{stubFetch([{id: "chat-1"},{result: "The answer"}]);constoutcome=awaitmakeAgent().run({prompt: "hi"}).then((v)=>`RESOLVED with ${JSON.stringify(v)}`,(e)=>`REJECTED with ${e.constructor.name}: ${e.message}`);console.log(`[case A] body {result:"The answer"} -> ${outcome}`);});it("response body {status: success, result: string}",async()=>{stubFetch([{id: "chat-1"},{status: "success",result: "The answer"}]);constoutcome=awaitmakeAgent().run({prompt: "hi"}).then((v)=>`RESOLVED with ${JSON.stringify(v)}`,(e)=>`REJECTED with ${e.constructor.name}: ${e.message}`);console.log(`[case B] body {status:"success",result:..} -> ${outcome}`);});it("response body {result: string, error: null} (control)",async()=>{stubFetch([{id: "chat-1"},{result: "The answer",error: null}]);constoutcome=awaitmakeAgent().run({prompt: "hi"}).then((v)=>`RESOLVED with ${JSON.stringify(v)}`,(e)=>`REJECTED with ${e.constructor.name}: ${e.message}`);console.log(`[case C] body {result:..,error:null} (ctrl) -> ${outcome}`);});});
Expected behavior
A 200 response whose body is {"result": "The answer"} (no error key) should resolve with "The answer". The code's own intent says as much:
The comment directly above the guard (remote.ts:346) states: // Check for actual error conditions (not just presence of error field) — an absent field is not an error condition.
Ten lines below, the same function treats { result: ... } as the success shape (remote.ts:374-375): if (typeof result === "object" && result !== null && "result" in result) { return result.result as T; }.
Smartphone (please complete the following information:)
N/A
Additional context
Actual output (verbatim, from the run above; reproduced identically by three independent runs):
[case A] body {result:"The answer"} -> REJECTED with Error: Remote agent execution failed: Remote agent execution failed: [object Object]
[case B] body {status:"success",result:..} -> REJECTED with Error: Remote agent execution failed: Remote agent execution failed: [object Object]
[case C] body {result:..,error:null} (ctrl) -> RESOLVED with "The answer"
Root cause: libraries/typescript/packages/agent/src/agents/remote.ts:347 — result.error !== null is true when the error key is absent (undefined !== null), so every 200 body without an explicit error key is classified as an error. Two adjacent details make genuine failures harder to diagnose too: remote.ts:348 interpolates result.error ?? String(result), which renders an object error value as [object Object], and the String(result).includes("failed to initialize") check at remote.ts:354 is dead for object bodies for the same reason (String({}) is "[object Object]").
Reachability: RemoteAgent is exported from the package root (src/index.ts:56), and both MCPAgent variants constructed with agentId delegate run() to it (src/agents/mcp_agent.ts:505-507, src/agents/mcp_agent_langchain.ts:1203-1205). Any consumer of the hosted-agent API whose backend returns a 200 body without an explicit error: null key hits this on every call.
A small fix would be to only fire on a real error value — e.g. if (result.status === "error" || result.error != null) (loose equality also covers undefined) — and interpolate JSON.stringify(result.error) instead of result.error ?? String(result) so genuine error messages stay readable. Happy to open a PR with this approach if wanted.
Related: I searched the issue tracker (RemoteAgent, remote agent execution failed, remote error null) and found no existing report covering this — #2413 concerns local-mode maxSteps, #1581 the browser entry bundling.
Disclosure: found and verified by an AI bug-hunting agent; the reproduction above was run locally against the repository at the commit stated, with no network access.
Reproduced this. Root cause: libraries/typescript/packages/agent/src/agents/remote.ts:347 — result.error !== null is true when the error key is absent (undefined !== null), so every 200 body without an explicit error key is classified as a failure.
Minimal reproduction:
cd libraries/typescript/packages/agent && npx vitest run tests/repro-remote-error-field.test.ts
Observed output:
[case A] body {result:"The answer"} -> REJECTED with Error: Remote agent execution failed: Remote agent execution failed: [object Object]
[case B] body {status:"success",result:..} -> REJECTED with Error: Remote agent execution failed: Remote agent execution failed: [object Object]
[case C] body {result:..,error:null} (ctrl) -> RESOLVED with "The answer"
Happy to open a PR with this fix, or to be assigned if you prefer to take it.
Activity
BlueX888 commentedon Sep 23, 2026
Reproduced this. Root cause: libraries/typescript/packages/agent/src/agents/remote.ts:347 — result.error !== null is true when the error key is absent (undefined !== null), so every 200 body without an explicit error key is classified as a failure.
Minimal reproduction:
Observed output:
Happy to open a PR with this fix, or to be assigned if you prefer to take it.
khandrew1 commentedon Oct 19, 2026
Fixed by #2651 and released in
@mcp-use/agent2.0.25 (mcp-use2.11.0). Closing.