gitbutlerapp/gitbutler · error

Remote with name already exists.

Error message

Remote with name ${sameNameRemote.name} already exists.

What it means

Thrown by remotesService.addRemote before invoking the backend, when a git remote with the requested name already exists on the project. Git remote names must be unique, so the service pre-validates the existing remote list to give a friendly error instead of a raw git failure.

Solutions

  1. Check existing remotes before calling addRemote and use a unique name.
  2. Fetch the remote list (remotesService.remotes(projectId)) and show a name-collision validation error in the UI before submitting.
  3. If the user intends to update, use a remote-update flow rather than add.

Example fix

// before
await remotesService.addRemote(projectId, 'origin', url);
// after
const names = (await remotesService.remotes(projectId)).map(r => r.name);
if (names.includes('origin')) throw new Error('Pick a different remote name');
await remotesService.addRemote(projectId, 'origin', url);
Defensive patterns

Strategy: validation

Validate before calling

const remotes = await remotesService.remotes(projectId);
if (remotes.some(r => r.name === name)) {
  throw new Error(`Remote "${name}" already exists`);
}
await remotesService.addRemote(projectId, name, url);

Try / catch

try {
  await remotesService.addRemote(projectId, name, url);
} catch (e) {
  if (String(e).includes('already exists')) showToast('Remote name already in use');
}

Prevention

When it happens

Trigger: Calling addRemote(projectId, name, url) where an existing remote's name exactly equals the given name (e.g. 'origin').

Common situations: User types a name that collides with 'origin' or an existing fork remote; re-running an 'apply from fork' flow; programmatic callers not checking remotes() first.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/065616cfd04dd781. Report an issue: GitHub.

Appendix: source

Thrown at apps/desktop/src/lib/git/remotesService.ts:22

export interface GitRemote {
	name?: string;
	url?: string;
}

export const REMOTES_SERVICE = new InjectionToken<RemotesService>("RemotesService");

export class RemotesService {
	constructor(private backend: IBackend) {}
	async remotes(projectId: string) {
		return await this.backend.invoke<GitRemote[]>("list_remotes", { projectId });
	}

	async addRemote(projectId: string, name: string, url: string) {
		const remotes = await this.remotes(projectId);

		const sameNameRemote = remotes.find((remote) => remote.name === name);
		if (sameNameRemote) {
			throw new Error(`Remote with name ${sameNameRemote.name} already exists.`);
		}

		const sameUrlRemote = remotes.find((remote) => remote.url === url);
		if (sameUrlRemote) {
			// This should not happen, and indicates we are incorrectly showing an "apply from fork"
			// button in the user interface.
			throw new Error(`Remote ${sameUrlRemote.name} with url ${sameUrlRemote.url} already exists.`);
		}

		return await this.backend.invoke<string>("add_remote", { projectId, name, url });
	}
}

View on GitHub (pinned to 58e5313667)