{"record":{"id":"7601d9e72112f2d9","repo":"lfnovo/open-notebook","slug":"search-failed-str-e","errorCode":null,"errorMessage":"Search failed: {str(e)}","messagePattern":"Search failed: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/routers/search.py","lineNumber":59,"sourceCode":"            # Text search\n            results = await text_search(\n                keyword=search_request.query,\n                results=search_request.limit,\n                source=search_request.search_sources,\n                note=search_request.search_notes,\n            )\n\n        return SearchResponse(\n            results=results or [],\n            total_count=len(results) if results else 0,\n            search_type=search_request.type,\n        )\n\n    except InvalidInputError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n    except DatabaseOperationError as e:\n        logger.error(f\"Database error during search: {str(e)}\")\n        raise HTTPException(status_code=500, detail=f\"Search failed: {str(e)}\")\n    except HTTPException:\n        raise\n    except OpenNotebookError:\n        raise\n    except Exception as e:\n        logger.error(f\"Unexpected error during search: {str(e)}\")\n        raise HTTPException(status_code=500, detail=f\"Search failed: {str(e)}\")\n\n\nasync def stream_ask_response(\n    question: str, strategy_model: Model, answer_model: Model, final_answer_model: Model\n) -> AsyncGenerator[str, None]:\n    \"\"\"Stream the ask response as Server-Sent Events.\"\"\"\n    try:\n        final_answer = None\n\n        # LangGraph accepts a partial state dict at runtime, but its typed\n        # overloads require the full state type (langgraph typing limitation).","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/api/routers/search.py#L41-L77","documentation":"500 raised when a DatabaseOperationError escapes during search — the underlying database (SurrealDB) operation failed. The original DB error message is appended to the detail.","triggerScenarios":"POST /api/search while SurrealDB is unreachable, the search index/table is missing, or a query times out; DatabaseOperationError is raised by the data layer and re-wrapped here.","commonSituations":"SurrealDB container stopped, schema migrations not run, network partition between API and DB, corrupt full-text index.","solutions":["Confirm SurrealDB is running (make database) and reachable on port 8000","Restart the API so automatic schema migrations run","Inspect the appended message and SurrealDB logs for the failing query","Rebuild search indexes if the error mentions index corruption"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const ok = await fetch('/health').then(r => r.ok); // or DB status endpoint\nif (!ok) showMaintenanceMessage();","typeGuard":null,"tryCatchPattern":"catch (e) {\n  if (e.status === 500 && /Search failed/.test(e.detail)) fallbackToLocalSearch();\n}","preventionTips":["Health-check SurrealDB before search features","Surface DB errors distinctly so ops can react"],"tags":["database","search","http-500","surrealdb"],"backgroundTag":"database-operation-failed","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}