{"record":{"id":"6e8b88bef2d0c9c6","repo":"abhigyanpatwari/GitNexus","slug":"duplicate-auto-sync-targetdir-targetdir-for-p","errorCode":null,"errorMessage":"Duplicate auto-sync targetDir ${targetDir} for ${previous} and ${remoteUrl}","messagePattern":"Duplicate auto-sync targetDir (.+?) for (.+?) and (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/auto-sync/runner.ts","lineNumber":461,"sourceCode":"  const items: AutoSyncWorkItem[] = [];\n  const targetOwners = new Map<string, string>();\n  for (const project of config.projects) {\n    let cloneRoot: AutoSyncWorkItem['cloneRoot'];\n    try {\n      cloneRoot = await deps.resolveCloneRoot(project.localPath);\n    } catch (err: unknown) {\n      for (const remoteUrl of project.remoteUrls) {\n        items.push({ project, remoteUrl, error: shortErrorMessage(err) });\n      }\n      continue;\n    }\n    for (const remoteUrl of project.remoteUrls) {\n      try {\n        const repoName = extractRepoNameFromRemoteUrl(remoteUrl);\n        const targetDir = getConfiguredRepoPath({ localPath: cloneRoot.root }, repoName, remoteUrl);\n        const previous = targetOwners.get(targetDir);\n        if (previous !== undefined) {\n          throw new Error(\n            `Duplicate auto-sync targetDir ${targetDir} for ${previous} and ${remoteUrl}`,\n          );\n        }\n        targetOwners.set(targetDir, remoteUrl);\n        items.push({ project, remoteUrl, cloneRoot, repoName, targetDir });\n      } catch (err: unknown) {\n        items.push({ project, remoteUrl, error: shortErrorMessage(err) });\n      }\n    }\n  }\n  return items;\n}\n\nasync function mapWithConcurrency<T, R>(\n  items: T[],\n  concurrency: number,\n  signal: AbortSignal | undefined,\n  worker: (item: T) => Promise<R>,","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/auto-sync/runner.ts#L443-L479","documentation":"buildWorkItems derives a targetDir for each remote URL of a project and enforces that each target directory is owned by exactly one remote URL. If two remote URLs resolve to the same local clone path, the run would race or clobber files, so it throws instead of proceeding.","triggerScenarios":"Calling buildWorkItems (via workItems) for a project whose remoteUrls list contains two URLs (e.g. https and ssh forms, or duplicates) that extractRepoNameFromRemoteUrl + getConfiguredRepoPath collapse into the same targetDir.","commonSituations":"A project configured with both an HTTPS and an SSH remote for the same repo; a copy-pasted duplicate remote URL; two distinct repos whose names normalize to the same directory in the clone root.","solutions":["Remove the duplicate remote URL from the project's remoteUrls config so each URL maps to a unique targetDir.","Configure a distinct clone root or repo path override (getConfiguredRepoPath) so colliding repos get separate directories.","Normalize your remote URLs to one scheme (all https or all ssh) to avoid scheme-based name collisions.","Rename one of the repos if two repo names resolve to the same directory name."],"exampleFix":"// before (project config)\n\"remoteUrls\": [\"https://github.com/acme/api.git\", \"git@github.com:acme/api.git\"]\n// after\n\"remoteUrls\": [\"https://github.com/acme/api.git\"]","handlingStrategy":"validation","validationCode":"const dirs = project.remoteUrls.map((u) =>\n  getConfiguredRepoPath({ localPath: cloneRoot.root }, extractRepoNameFromRemoteUrl(u), u),\n);\nif (new Set(dirs).size !== dirs.length) {\n  throw new Error('remoteUrls resolve to duplicate target directories');\n}","typeGuard":null,"tryCatchPattern":"try {\n  items = await workItems();\n} catch (err) {\n  if (String(err.message).startsWith('Duplicate auto-sync targetDir')) {\n    logger.error('fix project remoteUrls:', err.message);\n    return;\n  }\n  throw err;\n}","preventionTips":["Keep one canonical remote URL per project (https form).","Deduplicate remoteUrls in config parsing.","Ensure repo names uniquely map to directory names in the clone root."],"tags":["config","duplicate","auto-sync","path-collision"],"backgroundTag":"conflicting-config-options","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}