rohitg00/ai-engineering-from-scratch · error · ProtocolViolation
legacy probe did not prove the configured legacy era
Error message
legacy probe did not prove the configured legacy era
What it means
Raised by select_era when the fallback policy would downgrade to the legacy era, but the probe observation's kind is not one of the four outcomes that constitute safe evidence of a legacy server (empty, timeout, connection_closed, unrecognized). Any other outcome (e.g. a malformed error or unexpected payload) proves nothing about the configured legacy era, so the classifier refuses to guess.
Solutions
- Inspect the captured observation kind and match it against the safe-evidence set {empty, timeout, connection_closed, unrecognized}
- Fix the server or test fixture so the probe produces one of the recognized legacy-evidence outcomes
- Switch policy to strict if the deployment should hard-fail instead of falling back
- Re-run the modern discovery probe; a well-formed jsonrpc_error with a modern error code classifies as modern and never reaches this guard
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at phases/13-tools-and-protocols/31-mcp-conformance-versioning-and-operations/code/main.py:351 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/af5470ce7ac100cd.
Report an issue: GitHub.
Appendix: source
Thrown at phases/13-tools-and-protocols/31-mcp-conformance-versioning-and-operations/code/main.py:351
raise ValueError("policy must be strict or fallback")
kind = observation.get("kind")
if kind == "discover_success":
return "modern"
if kind == "jsonrpc_error" and observation.get("code") in MODERN_ERROR_CODES:
return "modern"
if policy == "strict":
raise ProtocolViolation("modern support was not proven; strict policy forbids fallback")
if kind not in {"empty", "timeout", "connection_closed", "unrecognized"}:
raise ProtocolViolation("probe outcome is not safe evidence for fallback")
if not legacy_allowed:
raise ProtocolViolation("legacy fallback is not allowlisted for this endpoint")
if not isinstance(legacy_evidence, dict):
raise ProtocolViolation("inconclusive modern probe is not positive legacy evidence")
if (
legacy_evidence.get("kind") != "initialize_success"
or legacy_evidence.get("protocolVersion") != LEGACY_VERSION
):
raise ProtocolViolation("legacy probe did not prove the configured legacy era")
return "legacy"
def notification_http_outcome(request: dict[str, Any]) -> tuple[int, None]:
if "id" in request:
raise ValueError("request has an id and is not a notification")
return 202, None
@dataclass(frozen=True)
class Transcript:
name: str
era: str
headers: dict[str, str]
request: dict[str, Any]
response_status: int
response_body: dict[str, Any] | None
capabilities: frozenset[str] = frozenset()View on GitHub (pinned to 39ea8a1c6d)