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

  1. Refresh the access token before fetching branches (call refreshGitlabToken first)
  2. Confirm the project path/ID passed to the branches endpoint is correct and the project exists
  3. Ensure the OAuth app has api/read_repository scope and the user has Developer+ access
  4. 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

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


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/68e4ef105e4acf38. Report an issue: GitHub.