rohitg00/ai-engineering-from-scratch · error · KeyError

unknown tool

Error message

unknown tool {name!r}

What it means

Lookup failure in ToolRegistry.get: no record exists under the requested name. Because register() enforces the naming pattern, an unknown name usually means the tool was never registered, was registered under a different name, or the registry instance differs from the one populated at startup.

Solutions

  1. List registry.names() to see what is actually registered
  2. Fix typos or casing in the requested name
  3. Ensure lookups go through the same registry instance that was populated
  4. Register the tool before serving requests that reference it
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at phases/19-capstone-projects/21-tool-registry-schema-validation/code/main.py:96 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/dddc2c4c04c5572a. Report an issue: GitHub.

Appendix: source

Thrown at phases/19-capstone-projects/21-tool-registry-schema-validation/code/main.py:96

        override: bool = False,
    ) -> ToolRecord:
        if not self._NAME_RE.match(name):
            raise ValueError(f"tool name {name!r} must match {self._NAME_RE.pattern}")
        if name in self._records and not override:
            raise ValueError(f"tool {name!r} already registered; pass override=True to replace")
        validate_schema_shape(schema)
        rec = ToolRecord(
            name=name, description=description, schema=schema, handler=handler,
            idempotent=idempotent, timeout_ms=timeout_ms,
        )
        if name not in self._records:
            self._order.append(name)
        self._records[name] = rec
        return rec

    def get(self, name: str) -> ToolRecord:
        if name not in self._records:
            raise KeyError(f"unknown tool {name!r}")
        return self._records[name]

    def names(self) -> list[str]:
        return list(self._order)

    def validate(self, name: str, args: Any) -> Ok | list[ValidationError]:
        rec = self.get(name)
        errors: list[ValidationError] = []
        _walk(rec.schema, args, "", errors)
        if errors:
            return errors
        return Ok()


def validate_schema_shape(schema: dict) -> None:
    """Reject schemas using keywords outside the supported subset."""
    if not isinstance(schema, dict):
        raise ValueError("schema must be a dict")

View on GitHub (pinned to 39ea8a1c6d)