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
- Confirm the exact registered prompt name before removal
- Catch KeyError to make removal idempotent
- 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
- Check the registered name (decorator may derive it from the function)
- Keep prompt names centralized as constants
- Confirm the prompt lives on this provider, not a mounted one
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
- Prompt {name!r} version {version!r} not found
- Tool {name!r} not found
- Tool {name!r} version {version!r} not found
- Resource {uri!r} not found
- Resource {uri!r} version {version!r} not found
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/b2a128b96361952e.
Report an issue: GitHub.