{"record":{"id":"06255d84f4e37ff9","repo":"BloopAI/vibe-kanban","slug":"failed-to-push-changes","errorCode":null,"errorMessage":"Failed to push changes","messagePattern":"Failed to push changes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/web-core/src/shared/actions/index.ts","lineNumber":1090,"sourceCode":"    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 {\n        const repo = await repoApi.getById(repoId);\n        if (repo?.path) {\n          await navigator.clipboard.writeText(repo.path);\n        }","sourceCodeStart":1072,"sourceCodeEnd":1108,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/actions/index.ts#L1072-L1108","documentation":"The generic failure branch of the push action: workspacesApi.push() returned success=false with an error that is NOT force_push_required, so the action throws a generic 'Failed to push changes' message. The specific backend cause is not surfaced in the message, only in the result envelope.","triggerScenarios":"execute() -> workspacesApi.push(workspaceId, { repo_id }) resolves { success: false } with any error other than type 'force_push_required' — auth failure, rejected non-fast-forward variants, hook rejections, network errors wrapped by the API, or repo not found.","commonSituations":"Expired/insufficient credentials for the remote; repository or workspace deleted remotely; pre-receive hooks rejecting the push; API/proxy connectivity problems.","solutions":["Log/inspect the full result.error object to find the underlying cause (the thrown message is generic).","Verify git credentials/permissions for the remote are valid and sufficient to push.","Confirm the workspace and repo still exist remotely; refresh workspace state.","Retry if a transient network error; check remote server/hook logs otherwise."],"exampleFix":"// before\nthrow new Error('Failed to push changes');\n// after\nconsole.error('push failed:', result.error);\nthrow new Error(result.error?.message ?? 'Failed to push changes');","handlingStrategy":"try-catch","validationCode":"// before pushing: check remote access\nconst remoteOk = await checkRemoteCredentials(repoId);\nif (!remoteOk) await promptReauthenticate();","typeGuard":"function hasPushError(r: { success: boolean; error?: { type?: string; message?: string } }): boolean {\n  return r.success === false && r.error != null;\n}","tryCatchPattern":"try {\n  await pushAction.execute(ctx, workspaceId, repoId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Failed to push changes') {\n    showError('Push failed — check credentials, remote hooks, and that the repo still exists.');\n  } else throw e;\n}","preventionTips":["Log the full result.error envelope — the generic message hides the real cause.","Keep git credentials/tokens fresh and scoped with push permission.","Verify the workspace and repo still exist remotely before pushing.","Check pre-receive hook requirements (signed commits, branch naming) before pushing."],"tags":["git","push","api-result","credentials"],"backgroundTag":"git-push-rejected","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}