NousResearch/hermes-agent · error · TypeError
register_provider() expects a TranscriptionProvider instance
Error message
register_provider() expects a TranscriptionProvider instance, got {type(provider).__name__} What it means
TypeError raised by TranscriptionProviderRegistry.register_provider() (agent/transcription_registry.py:73) when the object passed is not an instance of the TranscriptionProvider ABC. The registry enforces the ABC contract up front so a malformed plugin fails loudly at registration rather than silently breaking dispatch later.
Source
Thrown at agent/transcription_registry.py:73
_lock = threading.Lock()
def register_provider(provider: TranscriptionProvider, *, scope: Optional[str] = None) -> None:
"""Register a transcription provider.
Rejects:
- Non-:class:`TranscriptionProvider` instances (raises :class:`TypeError`).
- Empty/whitespace ``.name`` (raises :class:`ValueError`).
- Names colliding with a built-in (logs a warning, silently
ignores — built-ins-always-win invariant).
Re-registration (same ``name``) overwrites the previous entry and
logs a debug message — makes hot-reload scenarios (tests, dev
loops) behave predictably.
"""
if not isinstance(provider, TranscriptionProvider):
raise TypeError(
f"register_provider() expects a TranscriptionProvider instance, "
f"got {type(provider).__name__}"
)
name = provider.name
if not isinstance(name, str) or not name.strip():
raise ValueError("Transcription provider .name must be a non-empty string")
key = name.strip().lower()
if key in _BUILTIN_NAMES:
logger.warning(
"Transcription provider '%s' shadows a built-in name; registration "
"ignored. Built-in STT providers (%s) always win — pick a different "
"name.",
key, ", ".join(sorted(_BUILTIN_NAMES)),
)
return
with _lock:
target = _providers if scope is None else _scoped_providers.setdefault(scope, {})
existing = target.get(key)View on GitHub (pinned to c896c09c42)
Solutions
- Instantiate before registering: register_provider(MyProvider()) instead of register_provider(MyProvider).
- Import the ABC from the canonical location (agent.transcription_registry / the module that owns it) so isinstance matches.
- If the object is duck-typed on purpose, subclass TranscriptionProvider so the contract is explicit.
Example fix
# before
from my_stt import MyProvider # different base class
register_provider(MyProvider) # TypeError: got 'type'
# after
from agent.transcription_registry import TranscriptionProvider
class MyProvider(TranscriptionProvider): # implement the ABC
...
register_provider(MyProvider()) Defensive patterns
Strategy: type-guard
Validate before calling
from agent.transcription_registry import TranscriptionProvider, register_provider
def safe_register(provider) -> None:
if not isinstance(provider, TranscriptionProvider):
raise TypeError(f"expected TranscriptionProvider, got {type(provider).__name__}")
register_provider(provider) Type guard
from agent.transcription_registry import TranscriptionProvider
def is_transcription_provider(obj: object) -> bool:
return isinstance(obj, TranscriptionProvider) Try / catch
try:
register_provider(provider)
except TypeError as exc:
logger.error("plugin registration failed (not a TranscriptionProvider): %s", exc) Prevention
- Always register instances, never classes.
- Import the ABC from the owning module so isinstance checks match.
- Add a smoke test that loads each shipped plugin and registers it.
When it happens
Trigger: Calling register_provider(some_obj) where some_obj is e.g. a class (not an instance), a duck-typed object missing the ABC, a provider built against an older/different TranscriptionProvider base class, or None.
Common situations: A third-party STT plugin registers the class instead of an instance (register_provider(MyProvider)), or imports TranscriptionProvider from a vendored/copied module so isinstance fails despite identical shape; refactors that moved the ABC leave stale imports.
Related errors
- Transcription provider .name must be a non-empty string
- Preview mode — launching is disabled.
- no install root
- ${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest
- Remote connection is not ready yet. Try again in a moment.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/8ab0f39827e9c4a7.
Report an issue: GitHub.