PrefectHQ/fastmcp · error · KeyError
Template {uri_template!r} not found
Error message
Template {uri_template!r} not found What it means
remove_template(uri_template, version=None) matches ResourceTemplate components by their exact uri_template string; with no match it raises KeyError(f"Template {uri_template!r} not found"). Note the match is against the pattern itself, not concrete URIs derived from it.
Source
Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/local_provider.py:303
def remove_template(self, uri_template: str, version: str | None = None) -> None:
"""Remove resource template(s) from this provider's storage.
Args:
uri_template: The template URI pattern.
version: If None, removes ALL versions. If specified, removes only that version.
Raises:
KeyError: If no matching template is found.
"""
if version is None:
# Remove all versions
keys_to_remove = [
k
for k, c in self._components.items()
if isinstance(c, ResourceTemplate) and c.uri_template == uri_template
]
if not keys_to_remove:
raise KeyError(f"Template {uri_template!r} not found")
for key in keys_to_remove:
self._remove_component(key)
else:
# Remove specific version
key = f"{ResourceTemplate.make_key(uri_template)}@{version}"
if key not in self._components:
raise KeyError(
f"Template {uri_template!r} version {version!r} not found"
)
self._remove_component(key)
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.
View on GitHub (pinned to 1f02114297)
Solutions
- Pass the exact pattern string used at registration, placeholders included
- List registered ResourceTemplates and copy the uri_template verbatim
- Catch KeyError for idempotent teardown
Example fix
// before
provider.remove_template("weather/{city}") # registered as "weather://{city}"
// after
provider.remove_template("weather://{city}") Defensive patterns
Strategy: validation
Validate before calling
patterns = {c.uri_template for c in provider._components.values()
if isinstance(c, ResourceTemplate)}
if "weather://{city}" not in patterns:
return Type guard
def template_exists(provider, uri_template: str) -> bool:
return any(isinstance(c, ResourceTemplate) and c.uri_template == uri_template
for c in provider._components.values()) Try / catch
try:
provider.remove_template("weather://{city}")
except KeyError:
pass # template not registered Prevention
- Pass the verbatim registration pattern, including placeholders like {city}
- Never pass a concrete URI where the pattern is expected
- Store template patterns as constants reused at removal
When it happens
Trigger: provider.remove_template("weather://{city}") where the template was registered with a different pattern string (different placeholder names, braces style, or path) or was never added to this provider.
Common situations: Pattern-string drift after refactoring placeholder names ({city} vs {location}); attempting removal with a concrete URI instead of the template pattern; template registered on another provider.
Related errors
- Template {uri_template!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/db881103b15a77c7.
Report an issue: GitHub.