{"record":{"id":"0fa29c37f5b6957c","repo":"BloopAI/vibe-kanban","slug":"force-push-required-the-remote-branch-has-diverge","errorCode":null,"errorMessage":"Force push required. The remote branch has diverged.","messagePattern":"Force push required\\. The remote branch has diverged\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/web-core/src/shared/actions/index.ts","lineNumber":1086,"sourceCode":"    },\n  },\n\n  GitPush: {\n    id: 'git-push',\n    label: 'Push',\n    icon: ArrowUpIcon,\n    shortcut: 'X U',\n    requiresTarget: ActionTargetType.GIT,\n    isVisible: (ctx) =>\n      ctx.hasWorkspace &&\n      ctx.hasGitRepos &&\n      ctx.hasOpenPR &&\n      ctx.hasUnpushedCommits,\n    execute: async (ctx, workspaceId, repoId) => {\n      const result = await workspacesApi.push(workspaceId, { repo_id: repoId });\n      if (!result.success) {\n        if (result.error?.type === 'force_push_required') {\n          throw new Error(\n            'Force push required. The remote branch has diverged.'\n          );\n        }\n        throw new Error('Failed to push changes');\n      }\n      invalidateWorkspaceQueries(ctx.queryClient, workspaceId);\n    },\n  },\n\n  // === Repo-specific Actions (for command bar when selecting a repo) ===\n  RepoCopyPath: {\n    id: 'repo-copy-path',\n    label: 'Copy Repo Path',\n    icon: CopyIcon,\n    requiresTarget: ActionTargetType.GIT,\n    isVisible: (ctx) => ctx.hasWorkspace && ctx.hasGitRepos,\n    execute: async (_ctx, _workspaceId, repoId) => {\n      try {","sourceCodeStart":1068,"sourceCodeEnd":1104,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/actions/index.ts#L1068-L1104","documentation":"The push action calls workspacesApi.push(); when the backend detects the local branch and its remote counterpart have diverged, it returns an error envelope typed force_push_required. The action translates that typed error into this explicit message telling the user a force push (history rewrite) is needed rather than a normal push.","triggerScenarios":"execute() -> workspacesApi.push(workspaceId, { repo_id }) resolves with { success: false, error: { type: 'force_push_required' } } — remote commits were rewritten (amend/rebase) or another machine force-pushed, so a fast-forward push is impossible.","commonSituations":"Rebased or amended commits that were already pushed; collaborator force-pushed the shared branch; remote branch reset from another workspace; CI/bot rewriting history.","solutions":["Pull/rebase local work onto the remote branch, then push normally (preferred — preserves remote history).","If divergence is intentional, confirm and perform an explicit force push (ideally --force-with-lease).","Coordinate with collaborators before force pushing a shared branch.","Investigate what rewrote remote history to prevent recurrence."],"exampleFix":"// before\nconst result = await workspacesApi.push(workspaceId, { repo_id: repoId }); // fails: diverged\n// after\nif (!result.success && result.error?.type === 'force_push_required') {\n  await git.fetch();\n  await git.rebaseOnto('origin/' + branch); // or confirmForcePush flow\n  await workspacesApi.push(workspaceId, { repo_id: repoId, force: true });\n}","handlingStrategy":"validation","validationCode":"// before pushing: detect divergence client-side\nawait git.fetch();\nconst diverged = await git.isBranchDiverged(branch, 'origin/' + branch);\nif (diverged) await promptRebaseOrForcePush();","typeGuard":"function isForcePushRequired(e: unknown): e is { type: 'force_push_required' } {\n  return typeof e === 'object' && e !== null && (e as { type?: string }).type === 'force_push_required';\n}","tryCatchPattern":"try {\n  await pushAction.execute(ctx, workspaceId, repoId);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Force push required')) {\n    const ok = await confirmDialog('Remote branch diverged. Rebase or force push?');\n    if (ok) await pushWithForce(workspaceId, repoId);\n  } else throw e;\n}","preventionTips":["Rebase on the remote branch before pushing when commits were amended or rebased.","Prefer --force-with-lease over bare force push to avoid clobbering others' work.","Avoid rewriting history on shared branches; coordinate with collaborators.","Fetch before push to detect divergence early and choose the resolution path."],"tags":["git","push","force-push","branch-diverged"],"backgroundTag":"force-push-required","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}