{"record":{"id":"065616cfd04dd781","repo":"gitbutlerapp/gitbutler","slug":"remote-with-name-samenameremote-name-already-exists","errorCode":null,"errorMessage":"Remote with name ${sameNameRemote.name} already exists.","messagePattern":"Remote with name (.+?) already exists\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/lib/git/remotesService.ts","lineNumber":22,"sourceCode":"export interface GitRemote {\n\tname?: string;\n\turl?: string;\n}\n\nexport const REMOTES_SERVICE = new InjectionToken<RemotesService>(\"RemotesService\");\n\nexport class RemotesService {\n\tconstructor(private backend: IBackend) {}\n\tasync remotes(projectId: string) {\n\t\treturn await this.backend.invoke<GitRemote[]>(\"list_remotes\", { projectId });\n\t}\n\n\tasync addRemote(projectId: string, name: string, url: string) {\n\t\tconst remotes = await this.remotes(projectId);\n\n\t\tconst sameNameRemote = remotes.find((remote) => remote.name === name);\n\t\tif (sameNameRemote) {\n\t\t\tthrow new Error(`Remote with name ${sameNameRemote.name} already exists.`);\n\t\t}\n\n\t\tconst sameUrlRemote = remotes.find((remote) => remote.url === url);\n\t\tif (sameUrlRemote) {\n\t\t\t// This should not happen, and indicates we are incorrectly showing an \"apply from fork\"\n\t\t\t// button in the user interface.\n\t\t\tthrow new Error(`Remote ${sameUrlRemote.name} with url ${sameUrlRemote.url} already exists.`);\n\t\t}\n\n\t\treturn await this.backend.invoke<string>(\"add_remote\", { projectId, name, url });\n\t}\n}\n","sourceCodeStart":4,"sourceCodeEnd":35,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/apps/desktop/src/lib/git/remotesService.ts#L4-L35","documentation":"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.","triggerScenarios":"Calling addRemote(projectId, name, url) where an existing remote's name exactly equals the given name (e.g. 'origin').","commonSituations":"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.","solutions":["Check existing remotes before calling addRemote and use a unique name.","Fetch the remote list (remotesService.remotes(projectId)) and show a name-collision validation error in the UI before submitting.","If the user intends to update, use a remote-update flow rather than add."],"exampleFix":"// before\nawait remotesService.addRemote(projectId, 'origin', url);\n// after\nconst names = (await remotesService.remotes(projectId)).map(r => r.name);\nif (names.includes('origin')) throw new Error('Pick a different remote name');\nawait remotesService.addRemote(projectId, 'origin', url);","handlingStrategy":"validation","validationCode":"const remotes = await remotesService.remotes(projectId);\nif (remotes.some(r => r.name === name)) {\n  throw new Error(`Remote \"${name}\" already exists`);\n}\nawait remotesService.addRemote(projectId, name, url);","typeGuard":null,"tryCatchPattern":"try {\n  await remotesService.addRemote(projectId, name, url);\n} catch (e) {\n  if (String(e).includes('already exists')) showToast('Remote name already in use');\n}","preventionTips":["Always check the existing remote list before adding","Uniquely validate the name field in the add-remote form","Prefer update/overwrite flows when the remote exists"],"tags":["git","remote","duplicate"],"backgroundTag":"file-already-exists","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}