CustomLabs
Agents & tools

Why is our agent calling tools with IDs that don't exist?

Answer

Loose tool schemas — free-form string IDs, everything optional — give the model room to fill a gap with something plausible-looking instead of something real, and with no server-side validation catching the mismatch before execution, a confidently invented ID reaches a system that expects a real one.

Also known as hallucinated parameters, fabricated tool call arguments

Symptoms

What does this look like in production?

  • Tool calls fail with a 404 or "not found" at a noticeably higher rate than you would expect from legitimate user error
  • A rejected call's argument looks like a real ID in shape (right format, right length) but doesn't correspond to anything in the system
  • The invalid ID doesn't appear anywhere earlier in the conversation or in any prior tool result the agent received
  • The failure rate rises specifically on tasks where the agent must recall an identifier rather than one just handed to it in a prior step
Root cause

Why does it happen?

When a tool's schema accepts any string for an ID field and marks every field optional, the model is never forced to justify where a value came from — it can generate one that matches the expected shape from pattern alone, the same way it would complete plausible-looking code. If the server also skips validating that the ID exists before acting on it, the fabricated value sails straight through to execution, and the failure only surfaces once the downstream system rejects it or, worse, silently acts on the wrong record.

This is a schema and validation gap more than a model-quality gap — a model asked to fill in a field with no constraints and no requirement to cite its source will complete the pattern it was trained to produce, and a plausible ID is exactly that pattern.

Detect

How do you confirm it's this?

  • Track the rate of rejected/404 tool calls as a first-class metric, not just a red trace in the logs
  • For every rejected call, check whether the invalid argument appears anywhere in a prior tool result the agent actually received — if not, it was invented, not misremembered
  • Validate every tool call server-side against its schema and count validation failures separately from execution failures
  • Compare hallucination rate on ID fields with a required enum or lookup versus ID fields that are free-form strings
Fix

How do you fix it?

  1. Tighten schemas: enums, patterns, required fields

    Constrain ID fields to a known enum where the set is small, or a validated pattern where it isn't, and mark fields required rather than optional wherever the tool genuinely needs them to act correctly.

  2. Validate server-side and return a structured, actionable error

    Never trust that a model-generated ID exists — check it before acting, and when it doesn't, return an error the agent can act on ("no matching record for X") rather than a silent no-op.

  3. Give the agent a lookup tool instead of expecting recall

    If the agent needs to reference an existing record, give it a search or list tool to find the real ID rather than relying on it to remember or infer one from context.

  4. Never accept an ID that didn't come from a prior tool result

    Where practical, enforce at the orchestration layer that any ID passed to a mutating tool must trace back to a value returned by an earlier read/lookup call in the same run, not a value the model wrote from scratch.

Limits

What this doesn't cover

This covers fabricated identifiers specifically — a wrong ID that the user themselves supplied incorrectly, or one from truly stale cached context, is a different failure with a different fix. Confirm the value was never legitimately available to the agent before treating it as hallucination.

Not sure if this is the one?

A Ship Audit runs this full checklist against your actual system and hands back a written, prioritized plan.

Book a Ship Audit

navigate select esc close