different-ai/openwork · error · ProbeFailure

Catalog does not match pinned profile fixture ${profile.fixt

Error message

Catalog does not match pinned profile fixture ${profile.fixtureVersion}

What it means

Outside connection-readiness mode, the discovered tool catalog must exactly match the pinned profile fixture: no missing tools and no unexpected extras. Any set difference fails the probe with MCP_TOOL_DISCOVERY / profile_fixture_mismatch, citing the fixture version.

Source

Thrown at packages/enterprise-mcp-mock-server/src/testing/probe.ts:853

        if (sourceTool) discoveredTools.push(sourceTool)
      }
      if (!result.nextCursor) {
        catalogComplete = true
        break
      }
      cursor = result.nextCursor
    }
    if (!catalogComplete) {
      throw new ProbeFailure("MCP_TOOL_DISCOVERY", "mcp_pagination_limit", "Tool catalog exceeded the 25-page safety limit")
    }
    mutable.toolCount = toolNames.size
    if (toolNames.size === 0) throw new ProbeFailure("MCP_TOOL_DISCOVERY", "catalog_empty", "Tool catalog was protocol-valid but did not satisfy enterprise readiness because it was empty")
    if (mode !== "connection-readiness") {
      const expectedToolNames = new Set(profile.tools.map((tool) => tool.name))
      const missing = [...expectedToolNames].filter((name) => !toolNames.has(name))
      const unexpected = [...toolNames].filter((name) => !expectedToolNames.has(name))
      if (missing.length > 0 || unexpected.length > 0) {
        throw new ProbeFailure(
          "MCP_TOOL_DISCOVERY",
          "profile_fixture_mismatch",
          `Catalog does not match pinned profile fixture ${profile.fixtureVersion}`,
        )
      }
    }
    recordPassed(phases, "MCP_TOOL_DISCOVERY", startedAt, `Retrieved ${toolNames.size} unique tools with bounded pagination`)

    const fault = activeFault
    const shouldCall = options.callTool !== undefined || mode === "safe-read" || fault?.phase === "PROVIDER_AUTHORIZATION" || fault?.phase === "PROVIDER_EXECUTION"
    if (shouldCall) {
      const selected = options.callTool
        ? { name: options.callTool.name, arguments: options.callTool.arguments }
        : (() => {
            const mutationRequired = fault?.effect === "commit-then-disconnect"
            const tool = discoveredTools.find((candidate) => candidate.kind === (mutationRequired ? "mutation" : "read"))
            if (!tool) throw new ProbeFailure("MCP_TOOL_EXECUTION", "mcp_tool", "No suitable tool was available for the requested probe")
            return { name: tool.name, arguments: defaultArguments(tool.inputSchema) }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Diff the server's advertised tool names against profile.tools and reconcile the two sets.
  2. Remove unexpected debug/experimental tools or add the missing tools to the server registry.
  3. If the catalog change is intentional, update the pinned fixture and bump profile.fixtureVersion.
  4. Re-run the probe in the same non-connection-readiness mode and confirm no diff remains.

Example fix

// before: tool added to server but not the fixture
server.register(debugTool);
// after: either remove it or pin it in the fixture
// fixture: { fixtureVersion: "2", tools: [...existing, debugTool] }
Defensive patterns

Strategy: validation

Validate before calling

const expected = new Set(profile.tools.map((t) => t.name));
const actual = new Set(catalog.tools.map((t) => t.name));
const missing = [...expected].filter((n) => !actual.has(n));
const unexpected = [...actual].filter((n) => !expected.has(n));
if (missing.length || unexpected.length) {
  throw new Error(`Fixture drift — missing: ${missing}, unexpected: ${unexpected}`);
}

Try / catch

try {
  await probeEnterpriseMcpMockServer(options);
} catch (e) {
  if (e instanceof ProbeFailure && e.reason === "profile_fixture_mismatch") {
    // diff the catalog against the fixture and reconcile before retrying
  } else throw e;
}

Prevention

When it happens

Trigger: probeEnterpriseMcpMockServer (mode != connection-readiness) computes missing or unexpected tool names when diffing toolNames against profile.tools, and either list is non-empty.

Common situations: Mock server profile drift after editing tools without bumping fixtureVersion; server serving a stale or different fixture; extra debug tools registered on the server; a tool renamed in the fixture but not on the server.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/289dbbf943725948. Report an issue: GitHub.