Skip to content

[BUG] fetch_node and explore_rpg reject batch-only payloads (missing field "entity_id") #91

@rrva

Description

@rrva

Description

fetch_node and explore_rpg advertise a batch mode via entity_ids (an Option<Vec<String>>), and the doc comment on entity_ids says it "overrides entity_id when provided". The handlers in crates/rpg-mcp/src/tools.rs are written for either-or semantics — they check entity_ids first and only fall back to entity_id.

But the serde deserialization rejects any call that omits entity_id, because the field is declared String (required) rather than Option<String>. So every batch-only call fails before the handler ever runs.

Reproduction

Caller payload (verbatim from a real session):

rpg.fetch_node({
  "entity_ids": [
    "docker/fetch-runtime-config.mjs:main",
    "docker/fetch-runtime-config.mjs:fetchSsmEnv",
    "docker/fetch-runtime-config.mjs:fetchSecrets"
  ],
  "fields": "source,deps,features",
  "source_max_lines": 220
})

Error: tool call error: tool call failed for `rpg/fetch_node`
    Caused by:
        Mcp error: -32602: failed to deserialize parameters: missing field `entity_id`

Same failure mode reproduces against explore_rpg with a batch-only payload.

Root cause

crates/rpg-mcp/src/params.rs:27-36FetchNodeParams.entity_id: String (required).
crates/rpg-mcp/src/params.rs:40-44ExploreRpgParams.entity_id: String (required).

Fallback logic in handlers that never gets a chance to run:

  • crates/rpg-mcp/src/tools.rs:173-177 (fetch_node)
  • crates/rpg-mcp/src/tools.rs:231-235 (explore_rpg)

Serde rejects the payload at the boundary, so the else { vec![params.entity_id.as_str()] } branch is the only one ever reachable — which means batch mode is unreachable for any caller that doesn't also pass a (typically dummy) entity_id.

Why it looks intermittent

It's not timing-dependent — it's call-shape-dependent:

  • Calls with entity_id (single) always work.
  • Calls with entity_ids only (batch) always fail.
  • Calls with both fields work (and entity_ids wins per the doc comment).

Suggested fix

Make entity_id an Option<String> in both FetchNodeParams and ExploreRpgParams, then have the handlers return a clear "either entity_id or entity_ids is required" error when both are None. Matches the documented semantics and is a one-line type change plus a small match update per handler.

The bug has been present since the initial commit (verified via git log -S "entity_ids: Option") — it just hadn't been hit until a caller used the pure batch form.

Priority

Medium — the tool advertises a feature (batch mode) that is unreachable in its intended form. Callers can work around by passing a throwaway entity_id alongside entity_ids, but that defeats the documented interface and the doc comment is actively misleading.

PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions