gitbutlerapp/gitbutler · error · Error

No stack selected!

Error message

No stack selected!

What it means

Thrown in the new-commit flow when finalStackId is still falsy after the code already attempted to create a stack via createNewStack({projectId, branch: {name: finalBranchName, order: 0}}). The created/existing stack object came back without a usable id (`stack.id ?? undefined`), so there is no stack to commit into.

Source

Thrown at apps/desktop/src/components/commit/NewCommitView.svelte:81

			// TODO: Refactor this awkward fallback somehow.
			if (!finalBranchName) {
				finalBranchName = await stackService.fetchNewBranchName(projectId);
			}
			const parentId = commitAction?.parentCommitId;
			const insertBelow = commitAction?.insertBelow;

			if (!finalStackId) {
				const stack = await createNewStack({
					projectId,
					branch: { name: finalBranchName, order: 0 },
				});
				finalStackId = stack.id ?? undefined;
				finalBranchName = stack.heads[0]?.name; // Updated to access the name property
				uiState.global.draftBranchName.set(undefined);
			}

			if (!finalStackId) {
				throw new Error("No stack selected!");
			}

			if (!finalBranchName) {
				throw new Error("No branch selected!");
			}

			// Run commit-msg hook if hooks are enabled
			let finalMessage = message;
			if ($runCommitHooks) {
				const messageHookResult = await runMessageHook({ projectId, message });
				if (messageHookResult?.status === "failure") {
					showWarning("Commit message hook failed", messageHookResult.error);
					return;
				} else if (messageHookResult?.status === "message") {
					finalMessage = messageHookResult.message;
				}
			}

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Inspect the backend response/log for the createNewStack call to see why no id was returned.
  2. Open the project once in the GitButler UI so workspace initialization completes, then commit again.
  3. In code, check stack.id immediately after creation and surface the backend reason instead of falling through to the generic throw.
  4. Update the desktop app and backend to matching versions so the stack DTO shape agrees.

Example fix

// before
const stack = await createNewStack({
  projectId,
  branch: { name: finalBranchName, order: 0 },
});
finalStackId = stack.id ?? undefined;
// ...
if (!finalStackId) {
  throw new Error("No stack selected!");
}

// after
const stack = await createNewStack({
  projectId,
  branch: { name: finalBranchName, order: 0 },
});
if (!stack?.id) {
  showWarning("Could not create stack", "The backend returned no stack id");
  return;
}
finalStackId = stack.id;
Defensive patterns

Strategy: validation

Validate before calling

const stack = await createNewStack({ projectId, branch: { name: finalBranchName, order: 0 } });
if (stack?.id == null) {
  showWarning("Could not create stack", "The backend returned no stack id");
  return;
}
const finalStackId = stack.id;

Type guard

function hasStackId(stack: { id?: string | number | null } | null | undefined): stack is { id: string | number } {
  return stack != null && stack.id != null;
}

Try / catch

try {
  await createCommit(/* ... */);
} catch (e) {
  if (e instanceof Error && e.message === "No stack selected!") {
    showToast({ message: "Stack creation failed — retry the commit", style: "danger" });
  } else throw e;
}

Prevention

When it happens

Trigger: createNewStack resolves to an object whose id is null/undefined (backend declined or partially failed), or the call returned an empty success payload. The error only fires on the second check, i.e. creation was attempted and did not yield an id.

Common situations: First commit in a project whose workspace/virtual-branch state is not fully initialized; frontend/backend version mismatch changing the stack DTO; an invalid (empty or reserved) branch name passed to createNewStack.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/a608dc37260928b4. Report an issue: GitHub.