rohitg00/ai-engineering-from-scratch · error · ValueError
unknown prompt
Error message
unknown prompt
What it means
The name passed to prompts/get is a string but is not a key in the server's self.prompts registry. The simulator registers a fixed set of prompt templates at construction; anything else is unknown. Enumerate valid names first via prompts/list, whose response contains each prompt's exact name.
Source
Thrown at certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py:295
}
],
ttlMs=30_000,
cacheScope="private",
), []
if method == "prompts/list":
prompts = [
{"name": name, "description": self.prompts[name]}
for name in sorted(self.prompts)
]
return self._complete(
prompts=prompts, ttlMs=300_000, cacheScope="public"
), []
if method == "prompts/get":
name = params["name"]
if not isinstance(name, str):
raise ValueError("name must be a string")
if name not in self.prompts:
raise ValueError("unknown prompt")
return self._complete(
messages=[
{
"role": "user",
"content": {"type": "text", "text": self.prompts[name]},
}
]
), []
raise LookupError(f"Method not found: {method}")
def _call_tool(
self, params: dict[str, Any], metadata: dict[str, Any]
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
name = params["name"]
if not isinstance(name, str) or not name:
raise ValueError("name must be a non-empty string")
tool = self.tools.get(name)
if tool is None:View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Call prompts/list and use a name from the response exactly as returned
- Copy the name character-for-character — no renaming, casing changes, or pluralization
- If a needed prompt is missing, register it server-side or update the client's expected catalog
Example fix
# before
server.exchange("prompts/get", {"name": "sumarize", "_meta": meta})
# after
listed = server.exchange("prompts/list", {"_meta": meta})[0]
name = listed["prompts"][0]["name"]
server.exchange("prompts/get", {"name": name, "_meta": meta}) Defensive patterns
Strategy: validation
Validate before calling
listed = server.exchange("prompts/list", {"_meta": meta})[0]
names = {p["name"] for p in listed["prompts"]}
if name not in names:
raise LookupError(f"unknown prompt {name!r}; known: {sorted(names)}") Type guard
def prompt_exists(server, name: str) -> bool:
return name in getattr(server, "prompts", {}) Try / catch
try:
server.exchange("prompts/get", params)
except ValueError as e:
if str(e) == "unknown prompt":
params["name"] = pick_from_prompts_list() # reselect and retry once
else:
raise Prevention
- Discover prompt names via prompts/list and reference them verbatim
- Version your prompt catalog so client and server rename together
- Fail fast client-side with the known-name list instead of a server round trip
When it happens
Trigger: prompts/get with "summarize" when the registry only has "summarise" or "summary"; hardcoding a prompt name removed in a server update; querying prompts that exist on a different MCP server.
Common situations: Prompt catalogs renamed between versions; multi-server setups where a name is routed to the wrong server; docs referencing prompts this deployment does not install.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/3568c2e302715a11.
Report an issue: GitHub.