{"record":{"id":"eee6c146132ad13a","repo":"Mintplex-Labs/anything-llm","slug":"failed-to-fetch-documents-from-paperless-ngx-re","errorCode":null,"errorMessage":"Failed to fetch documents from Paperless-ngx: ${res.status}","messagePattern":"Failed to fetch documents from Paperless-ngx: (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"collector/utils/extensions/PaperlessNgx/PaperlessNgxLoader/index.js","lineNumber":43,"sourceCode":"   * @returns {Promise<{{[key: string]: any, content: string}[]}>} The documents with their content\n   */\n  async fetchAllDocuments() {\n    try {\n      const documents = [];\n      let nextUrl = `${this.baseUrl}/api/documents/`;\n      let page = 1;\n\n      while (nextUrl) {\n        console.log(`Fetching documents page ${page} from Paperless-ngx`);\n        try {\n          const data = await fetch(nextUrl, {\n            headers: {\n              \"Content-Type\": \"application/json\",\n              ...this.baseHeaders,\n            },\n          }).then((res) => {\n            if (!res.ok)\n              throw new Error(\n                `Failed to fetch documents from Paperless-ngx: ${res.status}`\n              );\n            return res.json();\n          });\n\n          const validResults = data.results.filter((doc) => doc?.id);\n          if (!validResults.length) break;\n\n          documents.push(...validResults);\n\n          if (data.next === nextUrl) break;\n          nextUrl = data.next || null;\n          page++;\n        } catch (error) {\n          console.error(\n            `Error fetching page ${page} from Paperless-ngx:`,\n            error\n          );","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/collector/utils/extensions/PaperlessNgx/PaperlessNgxLoader/index.js#L25-L61","documentation":"PaperlessNgxLoader.fetchAllDocuments throws (inside a per-page try) when the documents list endpoint returns non-ok. The inner try/catch logs and breaks the pagination loop rather than propagating, so a failed page stops further fetching but does not crash the call.","triggerScenarios":"GET /api/documents/ returns non-2xx: 401 (bad apiToken — note the \"Token <token>\" scheme, not Bearer), 403, 404 (wrong baseUrl), 5xx.","commonSituations":"Wrong apiToken; baseUrl pointing to the wrong origin (the constructor strips to origin); Paperless-ngx API path changed; token lacks read permissions.","solutions":["Confirm the token: `curl -H \"Authorization: Token <token>\" <baseUrl>/api/documents/`.","Verify baseUrl.origin is correct (the constructor strips to origin).","Check the logged status code in the per-page error.","Ensure the token has document read permissions."],"exampleFix":"// before\nif (!res.ok) throw new Error(`Failed to fetch documents from Paperless-ngx: ${res.status}`);\n\n// after — include status text + the page being fetched\nif (!res.ok) throw new Error(`Paperless-ngx ${res.status} ${res.statusText} on page ${page} (${nextUrl})`);","handlingStrategy":"try-catch","validationCode":"async function paperlessAuthOk(baseUrl, token) {\n  const r = await fetch(`${new URL(baseUrl).origin}/api/documents/?page_size=1`, {\n    headers: { Authorization: `Token ${token}` },\n  });\n  return r.ok;\n}","typeGuard":null,"tryCatchPattern":"// fetchAllDocuments swallows per-page errors and breaks the loop\nconst docs = await loader.fetchAllDocuments();\nif (docs.length === 0) { /* check logs for \"Failed to fetch documents from Paperless-ngx: <status>\" */ }","preventionTips":["Use the 'Token' scheme, not 'Bearer', for Paperless-ngx.","Pre-validate the token with a one-item request.","Watch the per-page error logs — they do not throw."],"tags":["paperless-ngx","http","integration","auth"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}