{"record":{"id":"d7394a5556522f3a","repo":"Mintplex-Labs/anything-llm","slug":"gitea-loader-unauthorized-request-for-endpoin","errorCode":null,"errorMessage":"[Gitea Loader]: Unauthorized request for ${endpoint}. Skipping.","messagePattern":"\\[Gitea Loader\\]: Unauthorized request for (.+?)\\. Skipping\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/utils/extensions/RepoLoader/GiteaRepo/RepoLoader/index.js","lineNumber":388,"sourceCode":"          return null;\n        }\n        const retryAfter = Number(response.headers.get(\"retry-after\")) || 60;\n        console.warn(\n          `[Gitea Loader]: Rate limit hit for ${endpoint}. Waiting ${retryAfter}s before retrying...`\n        );\n        await this.#wait(retryAfter * 1000);\n        return this.fetchJson(endpoint, retries + 1);\n      }\n\n      if (response.status === 401 || response.status === 403) {\n        console.warn(\n          `[Gitea Loader]: Unauthorized request for ${endpoint}. Skipping.`\n        );\n        return null;\n      }\n\n      if (!response.ok) {\n        console.warn(\n          `[Gitea Loader]: Unexpected status ${response.status} for ${endpoint}. Skipping.`\n        );\n        return null;\n      }\n\n      return await response.json();\n    } catch (e) {\n      console.error(`GiteaRepoLoader.fetchJson`, e);\n      return null;\n    }\n  }\n}\n\nmodule.exports = GiteaRepoLoader;\n","sourceCodeStart":370,"sourceCodeEnd":403,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/collector/utils/extensions/RepoLoader/GiteaRepo/RepoLoader/index.js#L370-L403","documentation":"fetchJson received 401 or 403 from the Gitea API, so the loader logs this and returns null for that endpoint — the affected items (branches, file pages) are silently omitted from the collected workspace. 401 means the token is missing/bad; 403 means the token is valid but its owner cannot read the repository.","triggerScenarios":"Expired or revoked Gitea access token; token without read scope on the target repo; repo made private or transferred away from the token owner; token pasted with whitespace/typos; loading a private repo anonymously.","commonSituations":"Tokens rotated on a policy but not updated in the data connector; organization repos where the token user is not a member; SSO-enforced Gitea rejecting plain PATs.","solutions":["Regenerate the Gitea personal access token and re-enter it in the data connector settings.","Confirm the token's scopes include read access to the target repository.","Verify the token owner can open the repo in a browser while logged in.","Check the token was pasted without quotes, spaces, or newlines."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Preflight the token before starting a Gitea sync:\nconst resp = await fetch(`${giteaBase}/api/v1/user`, {\n  headers: { Authorization: `token ${accessToken}` },\n});\nif (resp.status === 401 || resp.status === 403) {\n  throw new Error(`Gitea token rejected (${resp.status}) — fix credentials before syncing`);\n}","typeGuard":null,"tryCatchPattern":"const result = await loader.fetchJson(endpoint);\nif (result === null) console.warn(`endpoint ${endpoint} skipped — check token/permissions`);","preventionTips":["Validate the access token against /api/v1/user before launching the loader.","Store tokens in a trimmed state (strip whitespace/newlines) when saving connector config.","Rotate tokens on a calendar and update the connector immediately.","Prefer machine accounts that own the repos they read."],"tags":["gitea","http-401","http-403","access-token","repo-loader"],"backgroundTag":"http-401-unauthorized","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}