{"record":{"id":"8c4fa0b87c8a2205","repo":"bytedance/deer-flow","slug":"unsupported-fts5-retrieval-mode-mode","errorCode":null,"errorMessage":"unsupported FTS5 retrieval mode: {mode}","messagePattern":"unsupported FTS5 retrieval mode: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/retrieval.py","lineNumber":621,"sourceCode":"            encoded_scopes = [_scope_key(scope) for scope in scopes]\n        self._engine.replace_documents(documents, scopes=encoded_scopes)\n\n    def remove(self, fact_id: str, *, scope: dict[str, str | None]) -> None:\n        self._engine.remove_fact(self._document_id(fact_id, scope))\n\n    def search(\n        self,\n        query: str,\n        *,\n        scopes: list[dict[str, str | None]],\n        top_k: int,\n        mode: str,\n        filters: dict[str, Any] | None,\n    ) -> list[dict[str, Any]]:\n        if not query.strip() or top_k <= 0:\n            return []\n        if mode not in {\"hybrid\", \"fts5\", \"lexical\"}:\n            raise ValueError(f\"unsupported FTS5 retrieval mode: {mode}\")\n\n        filters = filters or {}\n        category = filters.get(\"category\")\n        if category is not None and not isinstance(category, str):\n            raise ValueError(\"retrieval category filter must be a string\")\n\n        results: list[dict[str, Any]] = []\n        per_scope_limit = top_k * 4\n        for scope in scopes:\n            scope_user, scope_agent = _scope_key(scope)\n            for candidate in self._engine.search(\n                query,\n                scope_user=scope_user,\n                scope_agent=scope_agent,\n                category=category,\n                top_k=per_scope_limit,\n            ):\n                fact = dict(candidate)","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/retrieval.py#L603-L639","documentation":"ValueError from FTS5RetrievalAdapter.search: the mode parameter is not one of the supported retrieval modes {'hybrid', 'fts5', 'lexical'}. Empty query or top_k<=0 return [] harmlessly, but an unknown mode is a programming/config error and rejected.","triggerScenarios":"Calling search(..., mode='semantic') or mode='vector' (not supported by the FTS5 adapter), or forwarding a user/config-supplied mode string unvalidated.","commonSituations":"Config file sets retrieval mode to a vector/semantic name on a deployment using the FTS5-only adapter; mode string typo ('Fts5', 'hybrid ' with space); newer caller sending a mode added to a different retrieval backend.","solutions":["Use one of: 'hybrid', 'fts5', or 'lexical' when calling the FTS5 adapter.","Validate mode against the adapter's supported set before calling (or expose it via the adapter) when it comes from config.","If you need semantic/vector retrieval, configure a retrieval backend that supports it rather than passing its mode name here.","Normalize case/whitespace on mode strings from user input."],"exampleFix":"# before\nresults = adapter.search(q, scopes=scopes, top_k=8, mode=\"semantic\")\n\n# after\nresults = adapter.search(q, scopes=scopes, top_k=8, mode=\"hybrid\")","handlingStrategy":"validation","validationCode":"SUPPORTED = {'hybrid', 'fts5', 'lexical'}\nmode = (mode or 'hybrid').strip().lower()\nif mode not in SUPPORTED:\n    raise ConfigError(f'retrieval mode {mode!r} unsupported; choose from {sorted(SUPPORTED)}')","typeGuard":"def is_supported_mode(mode) -> bool:\n    return isinstance(mode, str) and mode in {'hybrid', 'fts5', 'lexical'}","tryCatchPattern":"try:\n    results = adapter.search(q, scopes=scopes, top_k=k, mode=mode)\nexcept ValueError as e:\n    if 'unsupported FTS5 retrieval mode' in str(e):\n        results = adapter.search(q, scopes=scopes, top_k=k, mode='hybrid')  # known-good default\n    else:\n        raise","preventionTips":["Validate config-supplied retrieval modes at config load, not at query time.","Normalize mode strings (strip/lower) before use.","Keep the supported-mode set in one constant shared by config validation and the adapter."],"tags":["retrieval","config","validation","deermem","memory"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}