External Publication
Visit Post

"Runtime error" on all resource widgets in developer mode

OpenAI Developer Community April 24, 2026
Source

@mstoiber

On every request the ChatGPT Client:

  1. Calls resources/list — discovers all resources

  2. Calls resources/read for every resource — sequentially, one by one

  3. Calls tools/list — discovers tools

  4. Calls tools/call — executes a tool, which references a single resourceUri

  5. Renders one widget

Steps 1-2 download all resource HTML upfront even though only one widget is rendered per tool call. This repeats on every turn — nothing is cached across messages.

For N resources of ~150KB each, that’s N × 150KB re-downloaded every turn regardless of which tool is called. As apps grow in complexity (more screens, more widgets), the per-turn cost grows linearly while the value stays constant (1 widget rendered).

Resource filtering doesn’t work either. When a server returns a subset from resources/list, ChatGPT changes its tool selection behavior — it avoids calling tools whose associated resources are missing from the list, falling back to text responses. This means resources/list is implicitly coupled to tool planning, preventing servers from optimizing resource delivery independently.

Requested

  1. Lazy loading — fetch resources/read after a tool returns resourceUri, not before. The tool result already specifies which widget to render — there’s no need to prefetch all of them speculatively.

  2. Caching — resource URIs already include cache-busting identifiers (e.g. ui://widget-abc123). When the URI hasn’t changed between turns, skip the re-fetch.

  3. Decouple resources from tool selection — tool selection should be driven by tools/list and tool descriptions, not by which resources are in resources/list. Servers should be able to filter resources without it affecting which tools ChatGPT decides to call.

Why this matters

The prefetch-all model caps app complexity. Every resource added increases the per-turn bandwidth cost linearly, but only one widget is shown at a time. Multi-step apps (guided flows, wizards, checkout processes) naturally need many widgets — one per step — but the current behavior makes them progressively slower with each widget added.

With lazy loading or decoupled resource/tool selection, servers could dynamically serve only the widget needed for the current step. This removes the scaling ceiling and enables richer MCP apps without hitting timeout or bandwidth limits.

Environment

ChatGPT developer mode, MCP Apps with Streamable HTTP, April 2026. Reproducible with any MCP app that has 3+ resource-bound tools.

Discussion in the ATmosphere

Loading comments...