HKUDS/DeepTutor · error · ValueError
Capability not found: {resolved}
Error message
Capability not found: {resolved} What it means
A defensive invariant in `get_capability_contract`: after `resolve_capability` returned a canonical name, no manifest with that `name` was found in the registry. Normally unreachable (resolve checks the same manifests), so hitting it means the registry mutated between the two calls or manifests are inconsistent.
Source
Thrown at deeptutor/app/facade.py:96
contracts = []
for manifest in self.capabilities.get_manifests():
contracts.append(
{
**manifest,
"availability": self.get_capability_availability(manifest["name"]).__dict__,
}
)
return contracts
def get_capability_contract(self, value: str) -> dict[str, Any]:
resolved = self.resolve_capability(value)
for manifest in self.capabilities.get_manifests():
if manifest["name"] == resolved:
return {
**manifest,
"availability": self.get_capability_availability(resolved).__dict__,
}
raise ValueError(f"Capability not found: {resolved}")
def get_capability_availability(self, capability: str) -> CapabilityAvailability:
resolved = self.resolve_capability(capability)
if resolved == "math_animator":
available = importlib.util.find_spec("manim") is not None
return CapabilityAvailability(
name=resolved,
available=available,
install_hint=(
""
if available
else "Install with `pip install -e '.[math-animator]'` "
"or `pip install -r requirements/math-animator.txt`."
),
)
return CapabilityAvailability(name=resolved, available=True)
async def start_turn(View on GitHub (pinned to 3e82f13042)
Solutions
- Retry the call — the registry may have been mid-mutation
- Audit for concurrent registration/unregistration and serialize registry access
- If using a custom ToolRegistry/CapabilityRegistry, ensure get_manifests() is consistent with resolution lookups
Defensive patterns
Strategy: retry
Validate before calling
contracts = {c["name"] for c in app.get_capability_contracts()}
if name not in contracts:
# registry in flux or stale; refresh/retry registration
... Try / catch
for attempt in range(3):
try:
return app.get_capability_contract(name)
except ValueError:
time.sleep(0.2 * (attempt + 1))
raise Prevention
- Avoid registering/unregistering capabilities concurrently with lookups
- Serialize registry mutations behind a lock in custom registries
When it happens
Trigger: Calling `app.get_capability_contract(name)` while another thread/task unregisters or reloads capabilities between `resolve_capability` and the manifest loop; or a registry implementation whose `get_manifests()` returns a filtered/different set than the one used for resolution.
Common situations: Concurrent capability hot-reload during a WebSocket turn; a custom registry subclass that filters manifests inconsistently; monkeypatched manifests in tests.
Related errors
- Unknown capability `{requested}`. Available: {available}
- Knowledge base not initialized ({self.rag_provider}): {kb_na
- Failed to initialize index for KB '{kb_name}' from {len(sour
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/f7090bb8e2edfd23.
Report an issue: GitHub.