PrefectHQ/fastmcp · error · KeyError
Resource {uri!r} version {version!r} not found
Error message
Resource {uri!r} version {version!r} not found What it means
remove_resource with an explicit version constructs f"{Resource.make_key(uri)}@{version}" and raises KeyError if that exact key is not stored. The URI may exist but not with the supplied version string.
Source
Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/local_provider.py:282
Raises:
KeyError: If no matching resource is found.
"""
if version is None:
# Remove all versions
keys_to_remove = [
k
for k, c in self._components.items()
if isinstance(c, Resource) and str(c.uri) == uri
]
if not keys_to_remove:
raise KeyError(f"Resource {uri!r} not found")
for key in keys_to_remove:
self._remove_component(key)
else:
# Remove specific version
key = f"{Resource.make_key(uri)}@{version}"
if key not in self._components:
raise KeyError(f"Resource {uri!r} version {version!r} not found")
self._remove_component(key)
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_templateView on GitHub (pinned to 1f02114297)
Solutions
- Omit the version argument to remove all versions of the resource
- Check the registered version string matches exactly before removal
- Catch KeyError for idempotent teardown
Example fix
// before
provider.remove_resource("config://app", "2.0") # registered as "2"
// after
provider.remove_resource("config://app") # removes all versions Defensive patterns
Strategy: validation
Validate before calling
key = f"{Resource.make_key('config://app')}@1.0"
if key not in provider._components:
provider.remove_resource("config://app") # all versions Type guard
def resource_version_registered(provider, uri: str, version: str) -> bool:
return f"{Resource.make_key(uri)}@{version}" in provider._components Try / catch
try:
provider.remove_resource("config://app", "1.0")
except KeyError:
logger.info("resource version not present; nothing removed") Prevention
- Match version strings exactly between registration and removal
- Omit version in cleanup code to remove all versions at once
- Don't mix versioned and unversioned resources with the same URI
When it happens
Trigger: provider.remove_resource("config://app", "2") when the resource is registered unversioned, versioned as "2.0", or under a different version value.
Common situations: Version drift between add and remove calls; assuming a version exists after partial cleanup; mixing versioned and unversioned registration styles.
Related errors
- Tool {name!r} version {version!r} not found
- Resource {uri!r} not found
- Template {uri_template!r} version {version!r} not found
- Prompt {name!r} version {version!r} not found
- Tool {name!r} not found
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5c0b0f47dea6ee3e.
Report an issue: GitHub.