openai/codex-plugin-cc · error · Error
Unable to detect the repository default branch. Pass --base
Error message
Unable to detect the repository default branch. Pass --base <ref> or use --scope working-tree.
What it means
Thrown by detectDefaultBranch() when it cannot determine the repository's default branch. It first tries `git symbolic-ref refs/remotes/origin/HEAD`, then probes a fixed list of candidate branch names (main, master, trunk) against both local refs and origin remotes; if none resolve, it gives up. This is a heuristic guess, not a guarantee — repos with non-standard branch names (develop, default, release) defeat it.
Source
Thrown at plugins/codex/scripts/lib/git.mjs:115
const remoteHead = symbolic.stdout.trim();
if (remoteHead.startsWith("refs/remotes/origin/")) {
return remoteHead.replace("refs/remotes/origin/", "");
}
}
const candidates = ["main", "master", "trunk"];
for (const candidate of candidates) {
const local = git(cwd, ["show-ref", "--verify", "--quiet", `refs/heads/${candidate}`]);
if (local.status === 0) {
return candidate;
}
const remote = git(cwd, ["show-ref", "--verify", "--quiet", `refs/remotes/origin/${candidate}`]);
if (remote.status === 0) {
return `origin/${candidate}`;
}
}
throw new Error("Unable to detect the repository default branch. Pass --base <ref> or use --scope working-tree.");
}
export function getCurrentBranch(cwd) {
return gitChecked(cwd, ["branch", "--show-current"]).stdout.trim() || "HEAD";
}
export function getWorkingTreeState(cwd) {
const staged = gitChecked(cwd, ["diff", "--cached", "--name-only"]).stdout.trim().split("\n").filter(Boolean);
const unstaged = gitChecked(cwd, ["diff", "--name-only"]).stdout.trim().split("\n").filter(Boolean);
const untracked = gitChecked(cwd, ["ls-files", "--others", "--exclude-standard"]).stdout.trim().split("\n").filter(Boolean);
return {
staged,
unstaged,
untracked,
isDirty: staged.length > 0 || unstaged.length > 0 || untracked.length > 0
};
}View on GitHub (pinned to db52e28f4d)
Solutions
- Pass an explicit base ref: invoke the review with --base <ref> (e.g. --base origin/develop).
- Run the review in working-tree scope: use --scope working-tree to skip branch detection entirely.
- Make a candidate branch detectable: `git remote set-head origin -a` so symbolic-ref resolves, or rename/create a main|master|trunk branch.
- If your default branch is non-standard, set origin/HEAD: `git remote set-head origin <your-default-branch>`.
Example fix
// before
resolveReviewTarget(cwd, { scope: "branch" });
// after
resolveReviewTarget(cwd, { scope: "branch", base: "origin/develop" }); Defensive patterns
Strategy: validation
Validate before calling
import { execFileSync } from "node:child_process";
function hasDetectableDefaultBranch(cwd) {
// origin/HEAD set?
try {
execFileSync("git", ["-C", cwd, "symbolic-ref", "refs/remotes/origin/HEAD"], { stdio: "ignore" });
return true;
} catch {}
for (const c of ["main", "master", "trunk"]) {
for (const ref of [`refs/heads/${c}`, `refs/remotes/origin/${c}`]) {
try {
execFileSync("git", ["-C", cwd, "show-ref", "--verify", "--quiet", ref], { stdio: "ignore" });
return true;
} catch {}
}
}
return false;
}
// before calling resolveReviewTarget in branch/auto mode:
const opts = hasDetectableDefaultBranch(cwd)
? { scope: "branch" }
: { scope: "working-tree" }; // or { base: "origin/develop" } Try / catch
try {
resolveReviewTarget(cwd, { scope: "branch" });
} catch (err) {
if (/Unable to detect the repository default branch/.test(err.message)) {
// fall back to an explicit base or working-tree scope
resolveReviewTarget(cwd, { scope: "working-tree" });
} else {
throw err;
}
} Prevention
- Run `git remote set-head origin -a` after cloning so origin/HEAD is resolvable.
- Prefer passing --base <ref> explicitly in CI where branch layout is unknown.
- Default to --scope working-tree when you only care about uncommitted changes.
When it happens
Trigger: Calling resolveReviewTarget(cwd, {scope:'branch'}) (or scope 'auto' with a clean tree) on a repo where origin/HEAD is unset AND no local or remote branch named main/master/trunk exists. Triggered by the codex review command in branch/auto mode when --base is not supplied.
Common situations: Freshly cloned repo where `git remote set-head` was never run; a repo whose default branch is named `develop` or `release/*`; a bare or detached-HEAD checkout; CI environments that shallow-clone without origin/HEAD metadata; a local-only repo with no remote configured.
Related errors
- Unsupported review scope "${requestedScope}". Use one of: au
- Missing broker endpoint.
- Could not identify the current Claude transcript. Retry with
- git is not installed. Install Git and retry.
- This command must run inside a Git repository.
AI-assisted analysis of openai/codex-plugin-cc@db52e28f4d (2026-08-13).
Data as JSON: /api/errors/753960e2599c6a8e.
Report an issue: GitHub.