different-ai/openwork · error

MCP_APP_SANDBOX_RESOURCE_ASSIGNMENT_FAILED

MCP_APP_SANDBOX_RESOURCE_ASSIGNMENT_FAILED

Error message

The sandbox could not assign the HTML resource to its isolated document.

What it means

Assigning the HTML string to inner.srcdoc threw a JavaScript exception inside the sandbox's try block. The sandbox catches it and reports diagnostic MCP_APP_SANDBOX_RESOURCE_ASSIGNMENT_FAILED, meaning the isolated document could not receive the resource (assignment itself failed, distinct from a later load error).

Source

Thrown at apps/server/src/mcp-app-sandbox.ts:117

  });
  document.body.appendChild(inner);
  window.addEventListener("message", (event) => {
    if (event.source === window.parent) {
      if (event.origin !== hostOrigin) return;
      if (event.data?.method === "ui/notifications/sandbox-resource-ready") {
        const html = event.data?.params?.html;
        const sandbox = event.data?.params?.sandbox;
        if (typeof sandbox === "string" && /^(?:allow-scripts|allow-same-origin|\s)+$/.test(sandbox)) inner.setAttribute("sandbox", sandbox);
        if (typeof html !== "string") {
          notifyHost("ui/notifications/sandbox-diagnostic", { code: "MCP_APP_SANDBOX_RESOURCE_INVALID", message: "The sandbox received an invalid HTML resource payload." });
          return;
        }
        try {
          resourceAssigned = true;
          inner.srcdoc = html;
          notifyHost("ui/notifications/sandbox-resource-accepted");
        } catch {
          notifyHost("ui/notifications/sandbox-diagnostic", { code: "MCP_APP_SANDBOX_RESOURCE_ASSIGNMENT_FAILED", message: "The sandbox could not assign the HTML resource to its isolated document." });
        }
        return;
      }
      inner.contentWindow?.postMessage(event.data, "*");
      return;
    }
    if (event.source === inner.contentWindow && event.origin === ownOrigin) {
      window.parent.postMessage(event.data, hostTargetOrigin);
    }
  });
  window.parent.postMessage({ jsonrpc: "2.0", method: "ui/notifications/sandbox-proxy-ready", params: {} }, hostTargetOrigin);
})();
`;

export const MCP_APP_SANDBOX_PROXY_HTML = "<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><link rel=\"stylesheet\" href=\"/mcp-apps/sandbox.css\"><title>MCP App sandbox</title></head><body><script src=\"/mcp-apps/sandbox.js\"></script></body></html>";
export const MCP_APP_SANDBOX_PROXY_CSS = "html,body{width:100%;height:100%;margin:0;overflow:hidden;background:transparent}";

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Confirm document.body still contains `inner` when the message arrives; re-append or recreate the iframe if it was removed.
  2. Guard against teardown races: ignore sandbox-resource-ready messages after the sandbox is disposed.
  3. Retry the srcdoc assignment once on the next tick in case of a transient DOM state.
  4. In dev, disable hot-reload DOM replacement for the sandbox container or remount the whole sandbox after reload.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!document.body.contains(inner)) { /* remount the sandbox before posting the resource */ }

Try / catch

window.addEventListener("message", (e) => {
  if (e.data?.code === "MCP_APP_SANDBOX_RESOURCE_ASSIGNMENT_FAILED") {
    remountSandbox(); // recreate iframe, then re-post the resource
  }
});

Prevention

When it happens

Trigger: inner.srcdoc = html throwing — typically because the iframe was detached/removed from the DOM, the element is in a bad state, or a browser restriction blocks srcdoc assignment at that moment.

Common situations: Host navigated/reloaded and removed the iframe between posting the message and the sandbox handler running; the iframe element replaced during hot reload in dev; DOM teardown racing the postMessage handler.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/b5f8245a15e7475f. Report an issue: GitHub.