Dokploy/dokploy · error · Error
Failed to fetch branches: ${branchesResponse.statusText}
Error message
Failed to fetch branches: ${branchesResponse.statusText} What it means
GitLab's GET /projects/:id/repository/branches API returned a non-2xx status while listing branches for a project. The request uses the provider's stored accessToken as a Bearer token, so failures usually mean the token is invalid/expired or the project path is wrong/inaccessible.
Source
Thrown at packages/server/src/utils/providers/gitlab.ts:237
const allBranches = [];
let page = 1;
const perPage = 100; // GitLab's max per page is 100
const baseUrl = (
gitlabProvider.gitlabInternalUrl || gitlabProvider.gitlabUrl
).replace(/\/+$/, "");
while (true) {
const branchesResponse = await fetch(
`${baseUrl}/api/v4/projects/${input.id}/repository/branches?page=${page}&per_page=${perPage}`,
{
headers: {
Authorization: `Bearer ${gitlabProvider.accessToken}`,
},
},
);
if (!branchesResponse.ok) {
throw new Error(
`Failed to fetch branches: ${branchesResponse.statusText}`,
);
}
const branches = await branchesResponse.json();
if (branches.length === 0) {
break;
}
allBranches.push(...branches);
page++;
// Check if we've reached the total using headers (optional optimization)
const total = branchesResponse.headers.get("x-total");
if (total && allBranches.length >= Number.parseInt(total)) {
break;
}View on GitHub (pinned to 546686ea35)
Solutions
- Refresh the access token before fetching branches (call refreshGitlabToken first)
- Confirm the project path/ID passed to the branches endpoint is correct and the project exists
- Ensure the OAuth app has api/read_repository scope and the user has Developer+ access
- Read branchesResponse.status and body to distinguish 401 vs 403 vs 404
Example fix
// before
if (!branchesResponse.ok) {
throw new Error(`Failed to fetch branches: ${branchesResponse.statusText}`);
}
// after
if (!branchesResponse.ok) {
const body = await branchesResponse.text();
throw new Error(`Failed to fetch branches: ${branchesResponse.status} ${body}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
await refreshGitlabToken(gitlabId); // ensure fresh token before listing branches
Try / catch
try {
return await getGitlabBranches(...);
} catch (e) {
if (e instanceof Error && /fetch branches/.test(e.message)) {
// check project existence and scopes before surfacing to user
}
throw e;
} Prevention
- Refresh tokens before every GitLab API batch
- Require read_repository scope on the OAuth app
When it happens
Trigger: Expired or revoked access token (refresh not run before this call), token lacking read_repository scope, project deleted or path changed (404), or insufficient permission (403) on a group project.
Common situations: Access token expired between listing repositories and fetching branches; user lost access to the group; project renamed so the stored path 404s.
Related errors
- Failed to refresh token: ${response.statusText}
- BAD_REQUEST
- BAD_REQUEST
- Error ${response.status}: ${response.statusText}. Please ver
- Gitlab provider not found
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/68e4ef105e4acf38.
Report an issue: GitHub.