{"record":{"id":"6be13f62498cb3f8","repo":"gitbutlerapp/gitbutler","slug":"can-t-receive-a-change-without-it-s-source-or-commit","errorCode":null,"errorMessage":"Can't receive a change without it's source or commit","messagePattern":"Can't receive a change without it's source or commit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/lib/dragging/dropHandlers/commitDropHandler.ts","lineNumber":275,"sourceCode":"\t\t\t\t\t\t\t\t// Update the project state to point to the new commit if needed.\n\t\t\t\t\t\t\t\tupdateUiState(this.uiState, stackId, commitId, workspace.replacedCommits);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\"Change drop data must specify the source stackId\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"branch\":\n\t\t\t\t\tconsole.warn(\"Moving a branch into a commit is an invalid operation\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"worktree\":\n\t\t\t\t\tconsole.warn(\"Moving a branch into a commit is an invalid operation\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!(data.stackId && data.commitId)) {\n\t\t\t\tthrow new Error(\"Can't receive a change without it's source or commit\");\n\t\t\t}\n\t\t\tconst previousPathBytes =\n\t\t\t\tdata.change.status.type === \"Rename\" ? data.change.status.subject.previousPathBytes : null;\n\n\t\t\tconst sourceStackId = data.stackId;\n\t\t\tconst sourceCommitId = data.commitId;\n\n\t\t\tawait withStackBusy(\n\t\t\t\tthis.uiState,\n\t\t\t\tthis.projectId,\n\t\t\t\t{ commitId: sourceCommitId, stackIds: [sourceStackId] },\n\t\t\t\tasync () => {\n\t\t\t\t\tconst { workspace } = await this.stackService.uncommitChanges({\n\t\t\t\t\t\tprojectId: this.projectId,\n\t\t\t\t\t\tstackId: sourceStackId,\n\t\t\t\t\t\tcommitId: sourceCommitId,\n\t\t\t\t\t\tchanges: [\n\t\t\t\t\t\t\t{","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/apps/desktop/src/lib/dragging/dropHandlers/commitDropHandler.ts#L257-L293","documentation":"Thrown by UncommitDzHandler.ondrop in commitDropHandler.ts when a HunkDropDataV3 payload that is NOT uncommitted (i.e. it belongs to a commit) lacks data.stackId or data.commitId. Uncommitting a hunk requires knowing which stack and commit it is being moved out of, so the handler refuses to proceed.","triggerScenarios":"Dropping a HunkDropDataV3 with uncommitted=false but undefined stackId or commitId onto the uncommit dropzone; the accepts() guard (which checks uncommitted, commitId and stackId) was bypassed or the payload was built incompletely.","commonSituations":"A hunk dragged from a stale commit list where the commit has since been replaced (replacedCommits) leaving dangling ids; hunk drop data constructed by tests or code paths that never set commitId; serialization losing stackId/commitId fields.","solutions":["Make sure the hunk drag source sets stackId and commitId whenever the hunk belongs to a commit (uncommitted=false)","Check that the dropzone's accepts() rejects hunks without commitId/stackId so ondrop never sees them","Refresh the commit list so ids reference live commits, not replaced ones","In tests or programmatic drops, supply both stackId and commitId in HunkDropDataV3"],"exampleFix":"// before\nconst hunk = new HunkDropDataV3({ change, hunk, uncommitted: false, stackId: undefined, commitId: undefined });\n// after\nconst hunk = new HunkDropDataV3({ change, hunk, uncommitted: false, stackId: sourceStack.id, commitId: commit.id });","handlingStrategy":"type-guard","validationCode":"function canUncommitHunk(data: unknown): data is HunkDropDataV3 {\n  return data instanceof HunkDropDataV3 &&\n    !data.uncommitted && !!data.stackId && !!data.commitId;\n}","typeGuard":"function hasHunkSource(d: HunkDropDataV3): d is HunkDropDataV3 & { stackId: string; commitId: string } {\n  return !d.uncommitted && typeof d.stackId === 'string' && typeof d.commitId === 'string';\n}","tryCatchPattern":"try {\n  await handler.ondrop(hunkData);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"without it's source or commit\")) {\n    toast.error('Cannot uncommit: hunk source stack/commit is unknown');\n  } else throw e;\n}","preventionTips":["Set stackId and commitId on every hunk payload created from a commit","Mirror the handler's accepts() checks at the drag source","Avoid reusing stale payloads after commit replacements","Test hunk drop flows with committed and uncommitted variants"],"tags":["drag-and-drop","missing-required-field","desktop-app","frontend"],"backgroundTag":"missing-required-argument","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}