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 err

View on GitHub (pinned to c477a2959b)

Solutions

  1. Set both UpstreamRemote and UpstreamBranch (e.g. "origin" and "main")
  2. Or leave both empty to push to the branch's configured upstream
  3. 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

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


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/1e57f109deb640af. Report an issue: GitHub.