jesseduffield/lazygit · error
Must specify a remote if specifying a branch
Error message
Must specify a remote if specifying a branch
What it means
SyncCommands.PushCmdObj builds a `git push` command and rejects the combination where UpstreamBranch is set but UpstreamRemote is empty: `git push refs/heads/x:y` without a remote is not a valid push. The message (MustSpecifyOriginError) is lazygit's way of saying the push target is underspecified.
Source
Thrown at pkg/commands/git_commands/sync.go:33
func NewSyncCommands(gitCommon *GitCommon) *SyncCommands {
return &SyncCommands{
GitCommon: gitCommon,
}
}
// Push pushes to a branch
type PushOpts struct {
Force bool
ForceWithLease bool
CurrentBranch string
UpstreamRemote string
UpstreamBranch string
SetUpstream bool
}
func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (*oscommands.CmdObj, error) {
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
return nil, errors.New(self.Tr.MustSpecifyOriginError)
}
cmdArgs := NewGitCmd("push").
ArgIf(opts.Force, "--force").
ArgIf(opts.ForceWithLease, "--force-with-lease").
ArgIf(opts.SetUpstream, "--set-upstream").
ArgIf(opts.UpstreamRemote != "", opts.UpstreamRemote).
ArgIf(opts.UpstreamBranch != "", fmt.Sprintf("refs/heads/%s:%s", opts.CurrentBranch, opts.UpstreamBranch)).
ToArgv()
cmdObj := self.cmd.New(cmdArgs).PromptOnCredentialRequest(task)
return cmdObj, nil
}
func (self *SyncCommands) Push(task gocui.Task, opts PushOpts) error {
cmdObj, err := self.PushCmdObj(task, opts)
if err != nil {
return errView on GitHub (pinned to c477a2959b)
Solutions
- Set both UpstreamRemote and UpstreamBranch (e.g. "origin" and "main")
- Or leave both empty to push to the branch's configured upstream
- If the branch has no upstream yet, use SetUpstream with a remote specified, or configure it: `git push -u origin <branch>` once in a terminal
Example fix
// before
opts := PushOpts{CurrentBranch: "main", UpstreamBranch: "main"} // no remote -> error
// after
opts := PushOpts{CurrentBranch: "main", UpstreamRemote: "origin", UpstreamBranch: "main", SetUpstream: true} Defensive patterns
Strategy: validation
Validate before calling
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
return nil, fmt.Errorf("UpstreamRemote required when UpstreamBranch is set (got branch %q)", opts.UpstreamBranch)
}
cmdObj, err := syncCmd.PushCmdObj(task, opts) Try / catch
Validate PushOpts before calling PushCmdObj; on MustSpecifyOriginError, either fill UpstreamRemote from the branch's tracking config (`git rev-parse --abbrev-ref @{upstream}`) or drop both upstream fields and push to the tracked upstream. Prevention
- Always set remote and branch together in push option structs
- Set tracking once with `git push -u origin <branch>` so later pushes need neither field
- Default UpstreamRemote to "origin" in UI glue code
When it happens
Trigger: Calling Push with opts.UpstreamBranch set and opts.UpstreamRemote left ""; UI flows that set a branch override without a remote; programmatic callers assembling PushOpts partially.
Common situations: Setting the upstream branch field in the push options prompt without filling the remote; new remotes added after the push dialog was populated.
Related errors
- Invalid upstream. Must be in the format '<remote> <branchnam
- Expected renamed file
- Cannot open a pull request for a branch with no upstream
- Cannot fast-forward a branch with no upstream
- Cannot fast-forward a branch whose remote is not registered
AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15).
Data as JSON: /api/errors/1e57f109deb640af.
Report an issue: GitHub.