From 6ac84d4745cbc82eea0261fef5df592b0df9bfe4 Mon Sep 17 00:00:00 2001 From: olayinkaadelakun Date: Tue, 7 Apr 2026 20:00:02 -0400 Subject: [PATCH] fix: Indefinitely loading KB page for errors (#12295) * fix indefinitely loading KB page * [autofix.ci] apply automated fixes * retry for 5XX error * [autofix.ci] apply automated fixes * improved testcase name --------- Co-authored-by: Olayinka Adelakun Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com> Co-authored-by: Olayinka Adelakun --- .../base/langflow/api/v1/knowledge_bases.py | 4 +++- src/backend/tests/unit/test_knowledge_bases_api.py | 14 ++++++++++++++ .../use-get-knowledge-base-chunks.ts | 7 +++++++ .../__tests__/SourceChunksPage.test.tsx | 13 +++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/api/v1/knowledge_bases.py b/src/backend/base/langflow/api/v1/knowledge_bases.py index 44d6fdfb27..62ddbf41a1 100644 --- a/src/backend/base/langflow/api/v1/knowledge_bases.py +++ b/src/backend/base/langflow/api/v1/knowledge_bases.py @@ -552,6 +552,7 @@ async def get_knowledge_base_chunks( search: Annotated[str, Query(description="Filter chunks whose text contains this substring")] = "", ) -> PaginatedChunkResponse: """Get chunks from a specific knowledge base with pagination.""" + kb_path: Path | None = None try: kb_path = _resolve_kb_path(kb_name, current_user) @@ -631,7 +632,8 @@ async def get_knowledge_base_chunks( finally: client = None chroma = None - KBStorageHelper.release_chroma_resources(kb_path) + if kb_path is not None: + KBStorageHelper.release_chroma_resources(kb_path) @router.delete("/{kb_name}", status_code=HTTPStatus.OK) diff --git a/src/backend/tests/unit/test_knowledge_bases_api.py b/src/backend/tests/unit/test_knowledge_bases_api.py index 331abab2c9..548eb55351 100644 --- a/src/backend/tests/unit/test_knowledge_bases_api.py +++ b/src/backend/tests/unit/test_knowledge_bases_api.py @@ -694,6 +694,20 @@ class TestKnowledgeBaseAPI: assert data["page"] == 2 mock_collection.get.assert_called_with(include=["documents", "metadatas"], limit=10, offset=10) + @patch("langflow.api.v1.knowledge_bases.KBStorageHelper.get_root_path") + async def test_get_chunks_non_existent_kb_returns_404( + self, + mock_root, + client: AsyncClient, + logged_in_headers, + tmp_path, + ): + mock_root.return_value = tmp_path + + response = await client.get("api/v1/knowledge_bases/MissingKB/chunks", headers=logged_in_headers) + + assert response.status_code == 404 + class TestPerformIngestionTask: """Tests for the internal KBIngestionHelper.perform_ingestion background task.""" diff --git a/src/frontend/src/controllers/API/queries/knowledge-bases/use-get-knowledge-base-chunks.ts b/src/frontend/src/controllers/API/queries/knowledge-bases/use-get-knowledge-base-chunks.ts index b0de97809d..fedd547d8f 100644 --- a/src/frontend/src/controllers/API/queries/knowledge-bases/use-get-knowledge-base-chunks.ts +++ b/src/frontend/src/controllers/API/queries/knowledge-bases/use-get-knowledge-base-chunks.ts @@ -63,6 +63,13 @@ export const useGetKnowledgeBaseChunks: useQueryFunctionType< getChunksFn, { enabled: !!params?.kb_name, + retry: (failureCount, error: any) => { + const status = error?.response?.status; + if (typeof status === "number") { + return status >= 500 && failureCount < 3; + } + return failureCount < 3; + }, refetchOnWindowFocus: false, ...options, }, diff --git a/src/frontend/src/pages/MainPage/pages/knowledgePage/sourceChunksPage/__tests__/SourceChunksPage.test.tsx b/src/frontend/src/pages/MainPage/pages/knowledgePage/sourceChunksPage/__tests__/SourceChunksPage.test.tsx index e495bfc92b..62a880a136 100644 --- a/src/frontend/src/pages/MainPage/pages/knowledgePage/sourceChunksPage/__tests__/SourceChunksPage.test.tsx +++ b/src/frontend/src/pages/MainPage/pages/knowledgePage/sourceChunksPage/__tests__/SourceChunksPage.test.tsx @@ -93,6 +93,19 @@ describe("SourceChunksPage", () => { render(); expect(screen.getByText("Failed to load chunks")).toBeInTheDocument(); }); + + it("shows error message on 4xx errors", () => { + mockGetChunks.mockReturnValue({ + isLoading: false, + isError: true, + data: undefined, + error: { response: { status: 404 } }, + }); + + render(); + + expect(screen.getByText("Failed to load chunks")).toBeInTheDocument(); + }); }); describe("Empty state", () => {