{"record":{"id":"a9805a907dbd70d5","repo":"can1357/oh-my-pi","slug":"branch-localbranch-has-no-configured-push-remot","errorCode":null,"errorMessage":"branch ${localBranch} has no configured push remote","messagePattern":"branch (.+?) has no configured push remote","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/gh-pr-checkout.ts","lineNumber":235,"sourceCode":"\tisCrossRepository: boolean;\n}> {\n\tconst repository = vcs.requireGit(repoRoot);\n\tconst configPrefix = `branch.${localBranch}.`;\n\tconst [headRef, pushRemote, remote, prUrl, maintainerCanModifyValue, isCrossRepositoryValue] = await Promise.all([\n\t\trepository.configGet(`${configPrefix}ompPrHeadRef`, signal),\n\t\trepository.configGet(`${configPrefix}pushRemote`, signal),\n\t\trepository.configGet(`${configPrefix}remote`, signal),\n\t\trepository.configGet(`${configPrefix}ompPrUrl`, signal),\n\t\trepository.configGet(`${configPrefix}ompPrMaintainerCanModify`, signal),\n\t\trepository.configGet(`${configPrefix}ompPrIsCrossRepository`, signal),\n\t]);\n\tif (!headRef) {\n\t\tthrow new ToolError(`branch ${localBranch} has no PR push metadata; check it out via op: pr_checkout first`);\n\t}\n\n\tconst remoteName = pushRemote ?? remote;\n\tif (!remoteName) {\n\t\tthrow new ToolError(`branch ${localBranch} has no configured push remote`);\n\t}\n\n\treturn {\n\t\tremoteName,\n\t\tremoteBranch: headRef,\n\t\tremoteUrl: (await repository.remoteUrl(remoteName, signal)) ?? undefined,\n\t\tprUrl: prUrl ?? undefined,\n\t\tmaintainerCanModify:\n\t\t\tmaintainerCanModifyValue == null\n\t\t\t\t? undefined\n\t\t\t\t: [\"1\", \"true\", \"yes\", \"on\"].includes(maintainerCanModifyValue.toLowerCase()),\n\t\tisCrossRepository: [\"1\", \"true\", \"yes\", \"on\"].includes((isCrossRepositoryValue ?? \"\").toLowerCase()),\n\t};\n}\n\nexport function formatPrCheckoutResult(options: {\n\tdata: GhPrViewData;\n\tlocalBranch: string;","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/gh-pr-checkout.ts#L217-L253","documentation":"After finding ompPrHeadRef (2431), resolvePrBranchPushTarget computes the push remote as pushRemote ?? remote from branch.<localBranch>.* config. If neither key exists there is no remote to push to, so it throws. The checkout flow normally records one; this means the metadata is partially present but incomplete.","triggerScenarios":"branch.<localBranch>.ompPrHeadRef exists but both branch.<localBranch>.pushRemote and branch.<localBranch>.remote are unset — e.g. metadata was hand-seeded with only the head ref, or a checkout from an older tool version wrote fewer keys, or a config section was partially edited/removed.","commonSituations":"Manually restoring config after a botched edit; copying branches between clones without the full config section; older checkout tool versions that predate writing pushRemote.","solutions":["Set the push remote manually: `git config branch.<name>.pushRemote <remote>` (use the fork remote name, e.g. `upstream-pr-123` created by pr_checkout, or `origin` for same-repo PRs), then retry.","Re-run `op pr_checkout <PR>` with force=true to regenerate the complete metadata set for the branch.","For same-repo PRs, `git config branch.<name>.remote origin` is sufficient if pushRemote is absent."],"exampleFix":"// before: pr_push fails with 'no configured push remote'\n// after:\ngit config branch.my-fix.pushRemote origin\nop pr_push --branch my-fix","handlingStrategy":"validation","validationCode":"const pushRemote = await repo.configGet(`branch.${branch}.pushRemote`);\nconst remote = await repo.configGet(`branch.${branch}.remote`);\nif (!pushRemote && !remote) {\n  await repo.configSet(`branch.${branch}.pushRemote`, \"origin\"); // seed before calling the tool\n}","typeGuard":null,"tryCatchPattern":"try {\n  await op.prPush({ branch });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"no configured push remote\")) {\n    await git.config([\"branch\", branch, \"pushRemote\", \"origin\"]);\n    await op.prPush({ branch });\n  } else throw err;\n}","preventionTips":["Seed the full metadata set (ompPrHeadRef, pushRemote) whenever you hand-create PR branches.","Prefer re-running `op pr_checkout` over manually reconstructing config.","Avoid scripts that strip branch config sections.","Check `git config --get-regexp '^branch\\.'` before pushing an unfamiliar branch."],"tags":["git","config","pr-push"],"backgroundTag":"missing-git-config-metadata","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}