{"record":{"id":"0b2affe41190c2a8","repo":"Mintplex-Labs/anything-llm","slug":"unexpected-response-format-for-endpoint","errorCode":null,"errorMessage":"Unexpected response format for ${endpoint}:","messagePattern":"Unexpected response format for (.+?):","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"collector/utils/extensions/RepoLoader/GitlabRepo/RepoLoader/index.js","lineNumber":423,"sourceCode":"      }\n\n      if (response.status === 401) {\n        console.warn(\n          `[Gitlab Loader]: Unauthorized request for ${endpoint}. Skipping.`\n        );\n        return null;\n      }\n\n      if (!response.ok) {\n        console.warn(\n          `[Gitlab Loader]: Unexpected status ${response.status} for ${endpoint}. Skipping.`\n        );\n        return null;\n      }\n\n      const data = await response.json();\n      if (!Array.isArray(data)) {\n        console.warn(`Unexpected response format for ${endpoint}:`, data);\n        return [];\n      }\n\n      // GitLab omits x-total-pages for large repos, so use x-next-page\n      // as the sole pagination signal — it's empty on the last page.\n      const nextPage = response.headers.get(\"x-next-page\");\n      const totalPages = response.headers.get(\"x-total-pages\");\n      console.log(\n        `Gitlab RepoLoader: fetched ${endpoint} page ${requestData.page}${\n          totalPages ? `/${totalPages}` : \"\"\n        } with ${data.length} records.`\n      );\n\n      requestData.page = nextPage?.trim() ? Number(nextPage) : -1;\n\n      return data;\n    } catch (e) {\n      console.error(`RepoLoader.fetchNextPage`, e);","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/collector/utils/extensions/RepoLoader/GitlabRepo/RepoLoader/index.js#L405-L441","documentation":"The paginated GitLab endpoint answered 200 but response.json() was not an array — GitLab list endpoints return JSON arrays, so an object body means the request did not hit a real list endpoint (or the server returned a JSON error object with status 200). The loader warns and returns an empty list for that resource.","triggerScenarios":"apiBase misconfigured so the built /api/v4/... URL resolves to a non-API route that still returns JSON; a proxy in front of GitLab returning its own JSON object (e.g. an auth portal); a GitLab version whose endpoint shape differs; an error object like {\"message\":\"...\"} delivered with 200.","commonSituations":"Base URL including a trailing path segment that breaks routing; self-hosted GitLab behind SSO gateways; apiBase pointing at the web UI instead of the API host.","solutions":["Set apiBase to the bare GitLab root (e.g. https://gitlab.example.com) so /api/v4/... resolves correctly.","curl the exact failing URL with the token and inspect whether the body is an array.","Bypass or configure SSO/proxy gates so API paths are served by GitLab directly.","Confirm the GitLab version supports the endpoint being paginated."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Verify the endpoint returns an array before delegating to the loader:\nconst resp = await fetch(`${apiBase}/api/v4/projects/${id}/repository/tree?per_page=1`, {\n  headers: { 'PRIVATE-TOKEN': accessToken },\n});\nconst body = await resp.json();\nif (!Array.isArray(body)) throw new Error('apiBase does not resolve to the GitLab API — check base URL/proxy');","typeGuard":"function isGitlabListPayload(data) {\n  return Array.isArray(data);\n}","tryCatchPattern":null,"preventionTips":["Set apiBase to the bare GitLab host root, never a path that reroutes /api/v4.","Smoke-test one list endpoint with curl when configuring the connector.","Keep SSO/proxy gates from intercepting /api/v4 paths.","Watch for object bodies like {\"message\": ...} — they indicate routing, not GitLab, responses."],"tags":["gitlab","response-format","api-schema","repo-loader"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}