Skip to content

Every MCP tool call from an external client fails once with "has not been loaded yet" and succeeds on an identical retry — the error lists back the exact parameter names it was sent as possibly incorrect #759

Closed

Description

@proagentstore

Promoted from feedback rows b7b6c751-8ecd-43dd-86d0-d653ec9e8cbd and a0666f22-b36f-40c4-b7f0-bc879f9cdd2b, where this was recorded twice as a minor note (2026-08-15 and 2026-08-17). Both still status: open, issue_url: null. Still reproducing on 2026-08-24.

What happens

A first call to a PAGS MCP tool from an external client fails with either:

'mcp_..._coding_loop_start' has not been loaded yet. You do not have the correct parameter names for this tool. Valid input schema: {...}. Retry with the exact parameter names from the schema. You tried parameters: [instance_id, max_iterations, objective] — these may be incorrect.

or:

tool 'ProAgentStore:coding_loop_status' is not registered. This may indicate a tool name hallucination or a stale tool schema.

An immediate, byte-identical retry succeeds.

The error is self-contradicting

In the first form, the message prints the valid schema, then lists the parameters that were sent — and they match the schema exactly. [instance_id, objective, max_iterations] against a schema whose properties are token, instance_id, objective, max_iterations, dry_run with required: [instance_id, objective]. The call was well-formed. It is then told its parameter names "may be incorrect."

The real condition is that the schema had not been loaded server-side yet. The message attributes a transport/registration state to caller error, which sends the caller off correcting a call that was already correct.

Observed 2026-08-24

On a single session against instance a185b1db-c560-456d-9522-f7792bd95cca, this occurred on first call to coding_loop_start, coding_loop_status (twice), and call_instance_tool. Every one succeeded on identical retry. The 2026-08-17 row records the same: "every PAGS MCP tool in this session failed on first call with a 'has not been loaded yet' schema error and succeeded on an identical immediate retry."

Why it is worth more than a papercut

It doubles the call count on every tool from an external client, and it actively misleads. An agent that trusts the message will rewrite a correct call, guess different parameter names, or conclude the tool does not exist — the second error form explicitly suggests "tool name hallucination" for a tool that is registered and works one second later. It also burns a round trip on every first-touch tool in a chain, which on a voice or latency-sensitive surface is user-visible.

Asks

  1. Resolve the schema server-side before rejecting, or block the first call until registration completes, so a well-formed call is not refused for a server-side state.
  2. If a first-call failure is unavoidable, make it honest. Say the schema is not yet loaded and the call should be retried unchanged. Do not report the caller's parameters as possibly incorrect when they match the schema, and do not suggest hallucination for a registered tool.
  3. Related documentation gap noted in the same feedback row: call_instance_tool takes input, not args; github_update_issue takes labels as a comma-separated string and replaces rather than adds.

Activity

  1. serge-ivo commented on Aug 29, 2026

    @serge-ivo
    Contributor

    Diagnosis: client/harness-side — nothing to push

    Traced the complete stack. The PAGS MCP server does not emit either error string.

    Evidence

    "has not been loaded yet" and "possibly incorrect"

    grep -r "has not been loaded yet" workers/ packages/ store/ agents/
    (no output)
    

    The strings are absent from the entire server repo, the MCP SDK (@modelcontextprotocol/sdk@1.29.0), the agents/mcp library, and the mcp-remote proxy. They also do not appear in the Claude Desktop app bundle (/Applications/Claude.app/Contents/Resources/app.asar). These strings are synthesized by the Claude LLM itself as explanatory text when it needs to communicate a tool invocation failure to the user. The server cannot be responsible for text it never emits.

    "tool 'ProAgentStore:coding_loop_status' is not registered"

    The ProAgentStore:name namespace format is Claude Code's own client-side tool registry format. This message is generated by Claude Code when a tool is absent from its locally-held tool list. It is not a string the MCP server produces.

    Why the first call fails and the retry succeeds

    The MCP client (Claude Code / Claude Desktop) caches tool schemas across sessions. On a new session it sends a tools/list request, but may optimistically dispatch a tool call using the cached prior-session schema before the new tools/list response arrives. If the server's response lands (correctly) or the session is truly new and has no matching tool yet, the client generates the "not loaded yet" message and retries. By the time of the retry, the new tools/list has been processed and the schema is live — so the identical call succeeds.

    This is the classic MCP lazy-schema pattern documented in the spec. The server cannot pre-push schemas; it can only answer tools/list when asked.

    Server-side registration is not racing

    partyserver's #initialize() wraps onStart() (which calls await this.init()) in ctx.blockConcurrencyWhile(). This is a Cloudflare Durable Object primitive that holds every incoming request until the initialization completes. Tool registration (including await this.userGroups()) finishes before the first HTTP request is dispatched. There is no window where a tool call can arrive before registration is done.

    The userGroups() silent-failure edge case

    userGroups() can silently return an empty set on a cold-start API error. This would drop surface-gated tools (coding, apply, repo) from tools/list for that DO instance permanently. However:

    1. This would only affect surface-gated tools, not the always-on set. The issue reports "every PAGS MCP tool" failing, including tools like list_agents that are never gated — so this is not the cause of the reported behavior.
    2. A DO instance with empty groups would return those missing tools as absent from tools/list. A well-behaved client would see the difference and not attempt to call them. The misleading error message is generated only when the client does attempt a call using a stale cached schema.

    Ask #3 (doc gap)

    call_instance_tool already documents input correctly — both in the registered Zod schema (input: z.record(z.any())) and in README.md (tool + input). The github_update_issue labels semantics (REPLACE, not ADD; comma-separated) are documented in the tool's own description returned by list_instance_tools. No doc fix is needed.

    Recommendation

    This is external behavior that a server change cannot fix:

    • Short term: document in AGENTS.md that MCP clients using cached schemas may see a first-call retry on a fresh session; this is expected and the identical retry will succeed.
    • Medium term: if the userGroups() transient-failure scenario becomes a reported problem (surface-gated tools missing from tools/list), add a one-retry with a 200ms backoff inside userGroups(). But this is a separate, lower-priority issue.

    Not closing — leaving to the owner to decide whether to close as external or keep open for the doc note.

  2. added
    bugSomething isn't working
    mcpMCP server surface — the operator's instrument panel, not the product
    P3: laterDesign, strategy, or deferred pending a decision or demand
    documentationImprovements or additions to documentation
    invalidThis doesn't seem right
    and removed
    bugSomething isn't working
    on Sep 1, 2026
  3. serge-ivo commented on Sep 1, 2026

    @serge-ivo
    Contributor

    BA/dev triage — not actionable as a PAGS server bug

    Based on the diagnosis above and a code pass, this should not remain open as a server registration defect. The observed strings appear to be synthesized by external MCP clients/harnesses using stale or lazy-loaded tool schemas, and the identical retry succeeds after the client has processed tools/list.

    The server-side strings are not present in the repo, and the relevant server surfaces already expose/document the actual schemas. The remaining useful action is documentation, not a registration rewrite.

    Recommended disposition: close as external/client-side. If we keep a follow-up, make it a small docs note: on a fresh external MCP session, a first call may fail due to client schema loading; retry the same call unchanged.

    Do not pursue server-side registration fixes from this ticket. If userGroups() transient empty results become separately observed as gated tools missing from tools/list, file that as a distinct low-priority resilience issue with its own repro.

  4. proagentstore commented on Sep 11, 2026

    @proagentstore
    Author

    Fresh evidence, 2026-09-11: reproduced repeatedly (5-6+ times) in a single voice session driving MCP tools directly (get_instance_state, coding_loop_queue, coding_loop_start, github_read_issue among others) — first call fails with the exact "has not been loaded yet ... these may be incorrect" message quoting back correct parameter names, immediate identical retry succeeds every time. One call additionally returned a 30s approval timeout on the first two attempts before succeeding on the third. Consistent with this issue's existing description; adding as a recent, high-frequency occurrence rather than a new report.

  5. proagentstore commented on Sep 11, 2026

    @proagentstore
    Author

    Likely trigger identified for tonight's occurrences: the ProAgentStore/platform coder was actively pushing commits to main throughout this same session, each auto-triggering a Deploy MCP/Host Worker run (e.g. runs 917 and 918, deployed 2026-09-11 ~02:35 and ~03:01-03:28 UTC) that overlapped with the flaky tool calls. This fits the failure shape well: during a rolling worker deploy, an old instance can still be serving a request while a new instance is mid-registration of its tool schemas, so a client's first call can land on a not-yet-ready instance and get the misleading 'has not been loaded yet, parameters may be incorrect' response, while the immediate retry lands on an already-warm instance and succeeds. This wouldn't be the only cause of #759 (the issue's own history includes reports with no obvious deploy correlation), but it's a concrete, checkable contributor worth ruling in or out - e.g. by correlating future occurrences against Deploy MCP Worker run timestamps.

    Suggested best practice worth considering as part of the fix: rather than (or in addition to) the caller-facing message improvements already requested above, could the MCP/API surface a distinct, honest signal for this specific case - something like a 503 with a 'system update in progress, retry shortly' style response (possibly with a Retry-After hint), returned only during the brief window a worker instance is mid-deploy/mid-registration? That would let a caller (or an orchestrating agent) distinguish 'transient rollout window, safe to auto-retry' from a genuine tool/parameter problem, without having to guess from an error message that currently looks like caller error.

  6. serge-ivo commented on Sep 12, 2026

    @serge-ivo
    Contributor

    Closed as client-side — with the documentation this was labelled for, and the one real server residual split out

    Re-verified independently rather than taking the earlier triage on trust, and it holds.

    The error is not this server's sentence

    grep -rn "has not been loaded yet" workers packages store agents   -> no match
    

    Absent from the repo, from the pinned @modelcontextprotocol/sdk, and from the agents/mcp
    transport. ProAgentStore:coding_loop_status is a client-side namespacing format. The text is
    written by the client out of its own tool registry while it is still processing tools/list —
    which is exactly why it can list back parameters that match the schema and call them "possibly
    incorrect", and why an identical retry succeeds.

    There is no server-side registration race to lose

    Registration runs inside the Durable Object's blockConcurrencyWhile start, so a call cannot
    land on a half-registered server.

    The 2026-09-11 deploy-correlation theory does not survive this: a Cloudflare Worker deploy is
    atomic, not rolling, so there is no mid-registration instance to hit. What a redeploy does do
    is end the DO holding the session — and that failure already has an honest, distinct signal
    (Session not found, Invalid session id…), which is not the message reported here.

    The userGroups() theory does not survive it either: list_agents, platform_guide and
    sdk_reference are registered unconditionally, so a groups failure cannot explain "every PAGS
    MCP tool in this session".

    Ask 3 was already true

    • call_instance_tool takes input — in the Zod schema and in a description that explicitly
      warns against wrapping it (workers/mcp/src/instance-tools/base.ts:233).
    • github_update_issue documents labels as comma-separated and REPLACING, with the read-then-
      pass-existing-labels workaround spelled out (workers/api/src/lib/connectors/github.ts:478,484).

    Both are in the tool descriptions the client actually receives. No fix needed.

    What shipped — 031cf6a

    Asks 1 and 2 have no server-side target: the server cannot resolve a schema the client has not
    read yet, and it cannot make honest a message it does not emit. So what is actionable is the
    documentation label. platform-docs/mcp.md (§ Result And Error Shape) and AGENTS.md
    (§ Reading results) now both say: retry the identical call, do not rename parameters, do not
    conclude the tool is missing
    — and quote the three session failures the server does report,
    so a caller can tell a dead session from a client-cache blip.

    The server-side window that did exist

    Closed separately by 4983422 — userGroups() gets one bounded retry.

    The residual that commit's own comment names as unfixed is now #803: a failed lookup latches
    a truncated tool surface for the life of the DO, silently and unrecoverably. It is filed
    separately rather than kept here because it is not this issue's symptom — it does not recover on
    an identical retry, which is the defining feature of every report on this thread.

    Not verified

    Nothing here reproduces the client-side behaviour end to end — that needs the external client,
    not this repo. The claim is narrower and checkable: the strings are not ours, and there is no
    server state that could produce them. If it recurs, #803 is the thing to rule out first.

  7. added 2 commits that reference this issue on Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3: laterDesign, strategy, or deferred pending a decision or demanddocumentationImprovements or additions to documentationinvalidThis doesn't seem rightmcpMCP server surface — the operator's instrument panel, not the product

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions