requestModal() blurs the background but widget stays inline (never switches to modal)

Hi all,

When I call window.openai.requestModal() from inside my widget, the conversation blurs as if a modal is about to open, but the widget never actually switches to modal mode. It keeps rendering inline and no modal content appears.

Repro:

  1. From inside the widget iframe, call:

    await window.openai.requestModal({ params: { message: "hi" } });
    
  2. Background blurs. Promise resolves, no error.

  3. Poll the globals: displayMode and view.mode both stay "inline", and view.params is never set.

So the host seems to acknowledge the request (blur) but the widget never transitions to "modal".

Does anyone have any input one this ?

Thanks!

Hi,

requestModal() does not appear to convert the existing inline widget instance into a modal. It asks the ChatGPT host to open a host-controlled modal, which may render a separate instance of the current—or specified—UI template.

Because of that, polling displayMode, view.mode, or view.params from the original inline iframe may continue to return "inline". The modal parameters should be inspected from the widget instance mounted inside the modal.

I would first add initialization logging at the top of the widget bundle:

const instanceId = crypto.randomUUID();

console.log("[widget:init]", {
  instanceId,
  displayMode: window.openai?.displayMode,
  view: window.openai?.view,
});

window.addEventListener("openai:set_globals", (event) => {
  console.log("[widget:set_globals]", {
    instanceId,
    globals: event.detail?.globals,
  });
});

window.addEventListener("error", (event) => {
  console.error("[widget:error]", event.error ?? event.message);
});

window.addEventListener("unhandledrejection", (event) => {
  console.error("[widget:unhandledrejection]", event.reason);
});

Then try opening an explicitly registered modal template:

await window.openai.requestModal({
  template: "ui://widget/modal-test.html",
  params: {
    message: "hi",
    diagnosticId: crypto.randomUUID(),
  },
});

Please verify that:

  • ui://widget/modal-test.html is registered by the same MCP app;

  • the template URI exactly matches the registered resource URI;

  • the resource returns valid HTML and loads without JavaScript or CSP errors;

  • a second [widget:init] entry appears when the modal is requested;

  • the app has been refreshed and the test is performed in a new conversation.

The background blur and resolved Promise indicate that the host received or accepted the request, but they do not necessarily confirm that the modal template mounted successfully.

If no second widget instance is initialized—even with a minimal registered template—this may indicate a host-side issue. In that case, a useful bug report should include the ChatGPT surface, browser/version, template registration code, sanitized console logs, and confirmation that the problem also occurs in a new conversation.

Official reference: Build your ChatGPT UI – Apps SDK | OpenAI Developers

Best regards,

Kildere Sobral Irineu
Systems Analyst and Developer
Generative AI and AI Solutions Practitioner
Business Administrator | MBA in Management

https://www.linkedin.com/in/kilderesobralirineu/

Hey all, do you have an example conversation or an MCP server with reproduction? If so we can diagnose this quickly. (I’d recommend just pointing codex at tinymcp.dev.)

Hey Casey, you can try on our kitchen sink: https://everything.skybridge.tech, the useRequestModal tab. thanks!