{"record":{"id":"8ab0f39827e9c4a7","repo":"NousResearch/hermes-agent","slug":"register-provider-expects-a-transcriptionprovide","errorCode":null,"errorMessage":"register_provider() expects a TranscriptionProvider instance, got {type(provider).__name__}","messagePattern":"register_provider\\(\\) expects a TranscriptionProvider instance, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"agent/transcription_registry.py","lineNumber":73,"sourceCode":"_lock = threading.Lock()\n\n\ndef register_provider(provider: TranscriptionProvider, *, scope: Optional[str] = None) -> None:\n    \"\"\"Register a transcription provider.\n\n    Rejects:\n\n    - Non-:class:`TranscriptionProvider` instances (raises :class:`TypeError`).\n    - Empty/whitespace ``.name`` (raises :class:`ValueError`).\n    - Names colliding with a built-in (logs a warning, silently\n      ignores — built-ins-always-win invariant).\n\n    Re-registration (same ``name``) overwrites the previous entry and\n    logs a debug message — makes hot-reload scenarios (tests, dev\n    loops) behave predictably.\n    \"\"\"\n    if not isinstance(provider, TranscriptionProvider):\n        raise TypeError(\n            f\"register_provider() expects a TranscriptionProvider instance, \"\n            f\"got {type(provider).__name__}\"\n        )\n    name = provider.name\n    if not isinstance(name, str) or not name.strip():\n        raise ValueError(\"Transcription provider .name must be a non-empty string\")\n    key = name.strip().lower()\n    if key in _BUILTIN_NAMES:\n        logger.warning(\n            \"Transcription provider '%s' shadows a built-in name; registration \"\n            \"ignored. Built-in STT providers (%s) always win — pick a different \"\n            \"name.\",\n            key, \", \".join(sorted(_BUILTIN_NAMES)),\n        )\n        return\n    with _lock:\n        target = _providers if scope is None else _scoped_providers.setdefault(scope, {})\n        existing = target.get(key)","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/transcription_registry.py#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nfrom my_stt import MyProvider  # different base class\nregister_provider(MyProvider)   # TypeError: got 'type'\n\n# after\nfrom agent.transcription_registry import TranscriptionProvider\n\nclass MyProvider(TranscriptionProvider):  # implement the ABC\n    ...\n\nregister_provider(MyProvider())","handlingStrategy":"type-guard","validationCode":"from agent.transcription_registry import TranscriptionProvider, register_provider\n\ndef safe_register(provider) -> None:\n    if not isinstance(provider, TranscriptionProvider):\n        raise TypeError(f\"expected TranscriptionProvider, got {type(provider).__name__}\")\n    register_provider(provider)","typeGuard":"from agent.transcription_registry import TranscriptionProvider\n\ndef is_transcription_provider(obj: object) -> bool:\n    return isinstance(obj, TranscriptionProvider)","tryCatchPattern":"try:\n    register_provider(provider)\nexcept TypeError as exc:\n    logger.error(\"plugin registration failed (not a TranscriptionProvider): %s\", exc)","preventionTips":["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."],"tags":["typing","plugin","stt","registry","validation"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}