PrefectHQ/fastmcp · error · KeyError

Prompt {name!r} not found

Error message

Prompt {name!r} not found

What it means

remove_prompt(name, version=None) scans LocalProvider storage for Prompt components matching the name; with none found it raises KeyError(f"Prompt {name!r} not found"), indicating nothing was removed.

Source

Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/local_provider.py:333

    def remove_prompt(self, name: str, version: str | None = None) -> None:
        """Remove prompt(s) from this provider's storage.

        Args:
            name: The prompt name.
            version: If None, removes ALL versions. If specified, removes only that version.

        Raises:
            KeyError: If no matching prompt is found.
        """
        if version is None:
            # Remove all versions
            keys_to_remove = [
                k
                for k, c in self._components.items()
                if isinstance(c, Prompt) and c.name == name
            ]
            if not keys_to_remove:
                raise KeyError(f"Prompt {name!r} not found")
            for key in keys_to_remove:
                self._remove_component(key)
        else:
            # Remove specific version
            key = f"{Prompt.make_key(name)}@{version}"
            if key not in self._components:
                raise KeyError(f"Prompt {name!r} version {version!r} not found")
            self._remove_component(key)

    # =========================================================================
    # Provider interface implementation
    # =========================================================================

    async def _list_tools(self) -> Sequence[Tool]:
        """Return all tools."""
        return [v for v in self._components.values() if isinstance(v, Tool)]

    async def _get_tool(

View on GitHub (pinned to 1f02114297)

Solutions

  1. Confirm the exact registered prompt name before removal
  2. Catch KeyError to make removal idempotent
  3. Ensure the prompt is registered on this LocalProvider, not a mounted one

Example fix

// before
provider.remove_prompt("Summarize")  # registered as "summarize"
// after
provider.remove_prompt("summarize")
Defensive patterns

Strategy: try-catch

Validate before calling

names = {c.name for c in provider._components.values() if isinstance(c, Prompt)}
if "summarize" not in names:
    return

Type guard

def prompt_exists(provider, name: str) -> bool:
    return any(isinstance(c, Prompt) and c.name == name
               for c in provider._components.values())

Try / catch

try:
    provider.remove_prompt("summarize")
except KeyError:
    pass  # nothing to remove

Prevention

When it happens

Trigger: provider.remove_prompt("summarize") when the prompt was never registered, was already removed, is registered under a different name, or lives on a mounted provider rather than local storage.

Common situations: Cleanup code in tests removing prompts that failed to register; name typo/case mismatch; prompts added via decorators under a derived name differing from the assumed name.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/b2a128b96361952e. Report an issue: GitHub.