Mintplex-Labs/anything-llm · warning
${res.reason}
Error message
${res.reason} What it means
Thrown by DataConnector.github.branches when the backend proxy at /ext/github/branches returns JSON with success:false. The thrown message is res.reason, which the backend is expected to populate with the underlying GitHub API failure (bad credentials, repo not found, rate limit). The .catch logs, toasts, and returns {branches:[], error} so the UI degrades to an empty list rather than crashing. Note: if the backend omits reason, new Error(undefined) yields an empty message.
Source
Thrown at frontend/src/models/dataConnector.js:16
import { API_BASE } from "@/utils/constants";
import { baseHeaders } from "@/utils/request";
import showToast from "@/utils/toast";
const DataConnector = {
github: {
branches: async ({ repo, accessToken }) => {
return await fetch(`${API_BASE}/ext/github/branches`, {
method: "POST",
headers: baseHeaders(),
cache: "force-cache",
body: JSON.stringify({ repo, accessToken }),
})
.then((res) => res.json())
.then((res) => {
if (!res.success) throw new Error(res.reason);
return res.data;
})
.then((data) => {
return { branches: data?.branches || [], error: null };
})
.catch((e) => {
console.error(e);
showToast(e.message, "error");
return { branches: [], error: e.message };
});
},
collect: async function ({ repo, accessToken, branch, ignorePaths = [] }) {
return await fetch(`${API_BASE}/ext/github/repo`, {
method: "POST",
headers: baseHeaders(),
body: JSON.stringify({ repo, accessToken, branch, ignorePaths }),
})
.then((res) => res.json())View on GitHub (pinned to 526360e320)
Solutions
- Confirm the access token still has 'repo' (classic) or 'contents: read' (fine-grained) scope.
- Verify the repo string is exactly 'owner/name' and visible to the token owner.
- If res.reason mentions 'rate limit', wait for the window reset before retrying.
- Inspect backend logs - the proxy may be failing before it ever calls GitHub.
Example fix
// before
const { branches } = await DataConnector.github.branches({ repo, accessToken });
// after
const { branches, error } = await DataConnector.github.branches({ repo, accessToken });
if (error) showToast(`GitHub branches: ${error}`, 'error');
return branches; Defensive patterns
Strategy: validation
Validate before calling
function validateGithubArgs({ repo, accessToken }) {
if (!/^[-.\w]+\/[-.\w]+$/.test(repo ?? ''))
return 'repo must be "owner/name"';
if (!accessToken || accessToken.length < 20)
return 'accessToken looks invalid';
return null;
} Type guard
/** @param {unknown} r */
function isBranchesResult(r) {
return typeof r === 'object' && r !== null
&& Array.isArray(r.branches)
&& (r.error === null || typeof r.error === 'string');
} Try / catch
const result = await DataConnector.github.branches({ repo, accessToken });
if (result.error) {
showRetryableToast(result.error);
return [];
}
return result.branches; Prevention
- Validate the 'owner/name' format client-side to avoid a wasted round-trip.
- Cache branch lists (the call already uses force-cache) and invalidate on repo change.
- Prefer fine-grained PATs scoped to the minimum needed repository.
- Treat an empty branches array with a non-null error as a failure, not success.
When it happens
Trigger: Wrong or revoked GitHub access token; a repo string that does not exist or that the token cannot access; GitHub primary or secondary rate limit; backend cannot reach api.github.com.
Common situations: Classic PAT expired or lacked repo scope; repo typed as 'owner/name' with a typo; fine-grained PAT missing 'contents: read'; backend running in a region that hit GitHub's abuse rate limit.
Related errors
- res.reason
- Failed to sync GitHub file content. ${reason}
- ${response.error || "Failed to create slash command"}
- res.statusText
- Mistral Failed to embed: ${error.message}
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/40caf31456aed207.
Report an issue: GitHub.