{"record":{"id":"a608dc37260928b4","repo":"gitbutlerapp/gitbutler","slug":"no-stack-selected","errorCode":null,"errorMessage":"No stack selected!","messagePattern":"No stack selected!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/src/components/commit/NewCommitView.svelte","lineNumber":81,"sourceCode":"\t\t\t// TODO: Refactor this awkward fallback somehow.\n\t\t\tif (!finalBranchName) {\n\t\t\t\tfinalBranchName = await stackService.fetchNewBranchName(projectId);\n\t\t\t}\n\t\t\tconst parentId = commitAction?.parentCommitId;\n\t\t\tconst insertBelow = commitAction?.insertBelow;\n\n\t\t\tif (!finalStackId) {\n\t\t\t\tconst stack = await createNewStack({\n\t\t\t\t\tprojectId,\n\t\t\t\t\tbranch: { name: finalBranchName, order: 0 },\n\t\t\t\t});\n\t\t\t\tfinalStackId = stack.id ?? undefined;\n\t\t\t\tfinalBranchName = stack.heads[0]?.name; // Updated to access the name property\n\t\t\t\tuiState.global.draftBranchName.set(undefined);\n\t\t\t}\n\n\t\t\tif (!finalStackId) {\n\t\t\t\tthrow new Error(\"No stack selected!\");\n\t\t\t}\n\n\t\t\tif (!finalBranchName) {\n\t\t\t\tthrow new Error(\"No branch selected!\");\n\t\t\t}\n\n\t\t\t// Run commit-msg hook if hooks are enabled\n\t\t\tlet finalMessage = message;\n\t\t\tif ($runCommitHooks) {\n\t\t\t\tconst messageHookResult = await runMessageHook({ projectId, message });\n\t\t\t\tif (messageHookResult?.status === \"failure\") {\n\t\t\t\t\tshowWarning(\"Commit message hook failed\", messageHookResult.error);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (messageHookResult?.status === \"message\") {\n\t\t\t\t\tfinalMessage = messageHookResult.message;\n\t\t\t\t}\n\t\t\t}\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/apps/desktop/src/components/commit/NewCommitView.svelte#L63-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the backend response/log for the createNewStack call to see why no id was returned.","Open the project once in the GitButler UI so workspace initialization completes, then commit again.","In code, check stack.id immediately after creation and surface the backend reason instead of falling through to the generic throw.","Update the desktop app and backend to matching versions so the stack DTO shape agrees."],"exampleFix":"// before\nconst stack = await createNewStack({\n  projectId,\n  branch: { name: finalBranchName, order: 0 },\n});\nfinalStackId = stack.id ?? undefined;\n// ...\nif (!finalStackId) {\n  throw new Error(\"No stack selected!\");\n}\n\n// after\nconst stack = await createNewStack({\n  projectId,\n  branch: { name: finalBranchName, order: 0 },\n});\nif (!stack?.id) {\n  showWarning(\"Could not create stack\", \"The backend returned no stack id\");\n  return;\n}\nfinalStackId = stack.id;","handlingStrategy":"validation","validationCode":"const stack = await createNewStack({ projectId, branch: { name: finalBranchName, order: 0 } });\nif (stack?.id == null) {\n  showWarning(\"Could not create stack\", \"The backend returned no stack id\");\n  return;\n}\nconst finalStackId = stack.id;","typeGuard":"function hasStackId(stack: { id?: string | number | null } | null | undefined): stack is { id: string | number } {\n  return stack != null && stack.id != null;\n}","tryCatchPattern":"try {\n  await createCommit(/* ... */);\n} catch (e) {\n  if (e instanceof Error && e.message === \"No stack selected!\") {\n    showToast({ message: \"Stack creation failed — retry the commit\", style: \"danger\" });\n  } else throw e;\n}","preventionTips":["Validate the createNewStack response (id present) immediately and stop the flow there with a real error.","Ensure the project workspace is initialized before allowing the first commit.","Add a regression test where createNewStack returns an id-less payload."],"tags":["svelte","gitbutler","stack","commit","desktop"],"backgroundTag":"stack-creation-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}