{"record":{"id":"1b17619113f5f4fd","repo":"searxng/searxng","slug":"resolver-fqn-is-not-implemented","errorCode":null,"errorMessage":"resolver {fqn} is not implemented","messagePattern":"resolver (.+?) is not implemented","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"searx/favicons/proxy.py","lineNumber":80,"sourceCode":"    resolver_map: dict[str, str] = msgspec.field(default_factory=_initial_resolver_map)\n    \"\"\"The resolver_map is a key / value dictionary where the key is the name of\n    the resolver and the value is the fully qualifying name (fqn) of resolver's\n    function (the callable).  The resolvers from the python module\n    :py:obj:`searx.favicons.resolver` are available by default.\"\"\"\n\n    def get_resolver(self, name: str) -> Callable | None:\n        \"\"\"Returns the callable object (function) of the resolver with the\n        ``name``.  If no resolver is registered for the ``name``, ``None`` is\n        returned.\n        \"\"\"\n        fqn = self.resolver_map.get(name)\n        if fqn is None:\n            return None\n        mod_name, _, func_name = fqn.rpartition('.')\n        mod = importlib.import_module(mod_name)\n        func = getattr(mod, func_name)\n        if func is None:\n            raise ValueError(f\"resolver {fqn} is not implemented\")\n        return func\n\n    favicon_path: str = get_setting(\"ui.static_path\") + \"/themes/{theme}/img/empty_favicon.svg\"  # type: ignore\n    favicon_mime_type: str = \"image/svg+xml\"\n\n    def favicon(self, **replacements):\n        \"\"\"Returns pathname and mimetype of the default favicon.\"\"\"\n        return (\n            pathlib.Path(self.favicon_path.format(**replacements)),\n            self.favicon_mime_type,\n        )\n\n    def favicon_data_url(self, **replacements):\n        \"\"\"Returns data image URL of the default favicon.\"\"\"\n\n        cache_key = \", \".join(f\"{x}:{replacements[x]}\" for x in sorted(list(replacements.keys()), key=str))\n        data_url = DEFAULT_FAVICON_URL.get(cache_key)\n        if data_url is not None:","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/searxng/searxng/blob/9fea41204fdfa7a5cfa15b0ebd12904c520478ce/searx/favicons/proxy.py#L62-L98","documentation":"favicon proxy resolves a resolver by fully-qualified name from config (fqn) via importlib; if the imported module lacks the attribute, getattr returns None and ValueError is raised. (Note: for a truly missing attribute getattr raises AttributeError instead; None means the attribute exists but is set to None.)","triggerScenarios":"Configuring favicons.resolver or a strategy's favicon resolver to a dotted path where the symbol resolves to None (e.g. a placeholder or misspelled function that was renamed to None).","commonSituations":"Custom resolver modules, typos in FQNs, or version changes that renamed resolver functions.","solutions":["Verify the dotted path in your favicons config points to an existing function (check searx.favicons.resolvers module)","Fix typos in module/class names","Set the resolver key to null to use the default behavior"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import importlib\nmod_name, _, fn = fqn.rpartition('.')\nobj = getattr(importlib.import_module(mod_name), fn, None)\nif not callable(obj):\n    print('bad resolver fqn')","typeGuard":"def is_valid_resolver(fqn: str) -> bool:\n    mod_name, _, fn = fqn.rpartition('.')\n    try:\n        return callable(getattr(importlib.import_module(mod_name), fn, None))\n    except ImportError:\n        return False","tryCatchPattern":"try:\n    get_resolver(fqn)\nexcept (ValueError, AttributeError, ImportError) as e:\n    logger.error('favicon resolver %s invalid: %s', fqn, e)","preventionTips":["Use FQNs of bundled resolvers from searx.favicons.resolvers","Test custom resolvers import standalone before config"],"tags":["favicons","resolver","config"],"backgroundTag":"plugin-resolver-not-found","analyzedSha":"9fea41204fdfa7a5cfa15b0ebd12904c520478ce","analyzedAt":"2026-08-27T06:40:00.395Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}