{"record":{"id":"8935eb7d434cddc0","repo":"can1357/oh-my-pi","slug":"branch-localbranch-has-no-pr-push-metadata-che","errorCode":null,"errorMessage":"branch ${localBranch} has no PR push metadata; check it out via op: pr_checkout first","messagePattern":"branch (.+?) has no PR push metadata; check it out via op: pr_checkout first","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/gh-pr-checkout.ts","lineNumber":230,"sourceCode":"\tremoteName: string;\n\tremoteBranch: string;\n\tremoteUrl?: string;\n\tprUrl?: string;\n\tmaintainerCanModify?: boolean;\n\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};","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/gh-pr-checkout.ts#L212-L248","documentation":"resolvePrBranchPushTarget reads push metadata that op pr_checkout writes into git config under branch.<localBranch>.ompPrHeadRef (plus pushRemote/ompPrUrl/ompPrIsCrossRepository). If the ompPrHeadRef key is absent, the branch was not created by the PR checkout flow, so the tool refuses to guess where to push. This guards against pushing a plain local branch to the wrong remote/ref.","triggerScenarios":"Running `op pr_push` (or any call to target/resolvePrBranchPushTarget) on a local branch that was created by hand or via plain `git checkout -b` / `git checkout` of a PR ref, rather than via `op pr_checkout`. Also occurs if someone ran `git config --unset branch.<name>.ompPrHeadRef` or wiped .git/config.","commonSituations":"Developer manually created a branch expecting pr_push to work; branch was checked out in a fresh clone where local config was not copied; config was cleaned by a script or `git config --local --remove-section`.","solutions":["Check out the PR through the tool first: run `op pr_checkout <PR-number>` so it writes the push metadata, then retry the push.","Alternatively set the metadata manually: `git config branch.<name>.ompPrHeadRef <head-branch-name>` (and branch.<name>.pushRemote / ompPrUrl as needed) before pushing.","If you just want a normal push, use plain `git push -u <remote> <branch>` instead of the PR push flow."],"exampleFix":"// before: pr_push on hand-made branch fails\n// after: seed the metadata the tool expects\ngit config branch.my-fix.ompPrHeadRef my-fix\ngit config branch.my-fix.pushRemote origin\nop pr_push --branch my-fix","handlingStrategy":"validation","validationCode":"const headRef = await repo.configGet(`branch.${branch}.ompPrHeadRef`);\nif (!headRef) throw new Error(`${branch} was not checked out via op pr_checkout — run pr_checkout first`);","typeGuard":null,"tryCatchPattern":"try {\n  await op.prPush({ branch });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"no PR push metadata\")) {\n    await op.prCheckout({ prRef: prNumber, force: true }); // regenerate metadata, then retry\n    await op.prPush({ branch });\n  } else throw err;\n}","preventionTips":["Only push branches that were created by op pr_checkout.","Never hand-edit or remove branch.<name>.* config sections for PR branches.","When copying repos, preserve local git config or re-run pr_checkout in the new clone.","Document to the team that PR push requires checkout-through-tool."],"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"}