{"record":{"id":"a87982d60e040e1c","repo":"microsoft/autogen","slug":"subclasses-must-implement-from-config","errorCode":null,"errorMessage":"Subclasses must implement _from_config","messagePattern":"Subclasses must implement _from_config","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/tools/azure/_ai_search.py","lineNumber":660,"sourceCode":"            if not vector_fields or len(vector_fields) == 0:\n                raise ValueError(\"vector_fields must contain at least one field name for hybrid search\")\n\n            if not search_fields or len(search_fields) == 0:\n                raise ValueError(\"search_fields must contain at least one field name for hybrid search\")\n\n    @classmethod\n    @abstractmethod\n    def _from_config(cls, config: AzureAISearchConfig) -> \"BaseAzureAISearchTool\":\n        \"\"\"Create a tool instance from a configuration object.\n\n        This is an abstract method that must be implemented by subclasses.\n        \"\"\"\n        if cls is BaseAzureAISearchTool:\n            raise NotImplementedError(\n                \"BaseAzureAISearchTool is an abstract base class and cannot be instantiated directly. \"\n                \"Use a concrete implementation like AzureAISearchTool.\"\n            )\n        raise NotImplementedError(\"Subclasses must implement _from_config\")\n\n    @abstractmethod\n    async def _get_embedding(self, query: str) -> List[float]:\n        \"\"\"Generate embedding vector for the query text.\"\"\"\n        raise NotImplementedError(\"Subclasses must implement _get_embedding\")\n\n\n_allow_private_constructor = ContextVar(\"_allow_private_constructor\", default=False)\n\n\nclass AzureAISearchTool(EmbeddingProviderMixin, BaseAzureAISearchTool):\n    \"\"\"Azure AI Search tool for querying Azure search indexes.\n\n    This tool provides a simplified interface for querying Azure AI Search indexes using\n    various search methods. It's recommended to use the factory methods to create\n    instances tailored for specific search types:\n\n    1.  **Full-Text Search**: For traditional keyword-based searches, Lucene queries, or","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/azure/_ai_search.py#L642-L678","documentation":"The base implementation of _from_config raises NotImplementedError('Subclasses must implement _from_config') for any subclass that was instantiated but did not override the abstract classmethod. It fires when a subclass somehow bypasses ABC enforcement (e.g. via the module's _allow_private_constructor ContextVar path) or a subclass was left incomplete.","triggerScenarios":"Defining a class inheriting BaseAzureAISearchTool without implementing _from_config, then constructing it through internal/private paths that skip abstractmethod checks; calling _from_config on such an incomplete subclass.","commonSituations":"Mid-way through writing a custom tool subclass and testing before all abstract members exist; copy-pasting a subclass template that omits _from_config.","solutions":["Implement _from_config(cls, config: AzureAISearchConfig) -> Self in your subclass, constructing your instance from the config object.","Or inherit from the concrete AzureAISearchTool / EmbeddingProviderMixin stack instead of the raw base.","Run a quick isinstance/abstract check in tests: assert your class can be constructed normally (ABC will flag missing members at instantiation)."],"exampleFix":"# before\nclass MyTool(BaseAzureAISearchTool):\n    ...\n# after\nclass MyTool(BaseAzureAISearchTool):\n    @classmethod\n    def _from_config(cls, config: AzureAISearchConfig) -> 'MyTool':\n        return cls(name=config.name, endpoint=config.endpoint, index_name=config.index_name, credential=config.credential)","handlingStrategy":"type-guard","validationCode":"def subclass_is_complete(cls) -> bool:\n    from autogen_ext.tools.azure._ai_search import BaseAzureAISearchTool\n    return issubclass(cls, BaseAzureAISearchTool) and '_from_config' in cls.__dict__","typeGuard":"def implements_from_config(cls) -> bool:\n    return any('_from_config' in vars(c) for c in cls.__mro__ if c is not object)","tryCatchPattern":null,"preventionTips":["Satisfy every abstractmember of BaseAzureAISearchTool before writing tests; instantiation of a complete subclass fails fast via ABC.","Add an abstract-class completeness test: `test_subclass_implements_all_abstract_methods()`.","Prefer composing with AzureAISearchTool / EmbeddingProviderMixin over subclassing the raw base."],"tags":["azure","azure-ai-search","abstract-class","subclassing","not-implemented"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}