abhigyanpatwari/GitNexus · error
group path ${groupPath} is already mapped to ${config.repos[
Error message
group path ${groupPath} is already mapped to ${config.repos[groupPath]} What it means
addRepoToGroup refuses to overwrite an existing mapping in a group's group.yaml. Each repo path in an auto-sync group may map to exactly one registry name; if the path is already mapped to a different name, the mapping is treated as conflicting and thrown rather than silently overwritten. If the path is already mapped to the SAME registry name, the function returns false (no-op) instead of throwing.
Source
Thrown at gitnexus/src/core/auto-sync/runner.ts:409
repoName: string,
remoteUrl?: string,
): string {
if (!remoteUrl) return path.resolve(project.localPath, repoName);
const identity = getAutoSyncRepoIdentity(remoteUrl);
return path.resolve(project.localPath, ...identity.split('/').slice(0, -1), repoName);
}
export async function addRepoToGroup(
project: Pick<AutoSyncProjectConfig, 'groupName'>,
groupPath: string,
registryName = groupPath,
): Promise<boolean> {
if (!project.groupName) return false;
const groupDir = getGroupDir(getDefaultGitnexusDir(), project.groupName);
const config = await loadGroupConfig(groupDir);
if (config.repos[groupPath] === registryName) return false;
if (config.repos[groupPath] !== undefined) {
throw new Error(`group path ${groupPath} is already mapped to ${config.repos[groupPath]}`);
}
config.repos[groupPath] = registryName;
await writeGroupConfigAtomic(path.join(groupDir, 'group.yaml'), config);
return true;
}
export function getAutoSyncRepoIdentity(remoteUrl: string): string {
validateAutoSyncRemoteUrl(remoteUrl);
const [, host, remotePath] = /^git@([^:\s/]+):([^\s]+)$/.exec(remoteUrl.trim())!;
return `${host.toLowerCase()}/${remotePath.replace(/\.git$/i, '')}`;
}
export async function syncGroupByName(groupName: string): Promise<void> {
const groupDir = getGroupDir(getDefaultGitnexusDir(), groupName);
const config = await loadGroupConfig(groupDir);
await syncGroup(config, { groupDir });
}
View on GitHub (pinned to 0d1aed942f)
Solutions
- Check the existing mapping with loadGroupConfig and remove or correct config.repos[groupPath] in group.yaml before re-adding.
- Pass the same registryName that is already mapped if your intent is a no-op (the function returns false instead of throwing).
- Use a different groupPath for the new repo if the old mapping is intentional.
- Delete the stale group.yaml (or the single mapping) if the group config is known to be corrupt.
Example fix
// before
await addRepoToGroup(project, 'services/api', 'new-registry-name');
// throws: already mapped to 'old-registry-name'
// after
const config = await loadGroupConfig(groupDir);
if (config.repos['services/api'] !== 'new-registry-name') {
delete config.repos['services/api'];
await writeGroupConfigAtomic(path.join(groupDir, 'group.yaml'), config);
}
await addRepoToGroup(project, 'services/api', 'new-registry-name'); Defensive patterns
Strategy: validation
Validate before calling
const config = await loadGroupConfig(groupDir);
if (config.repos[groupPath] !== undefined && config.repos[groupPath] !== registryName) {
throw new Error(`conflict: ${groupPath} mapped to ${config.repos[groupPath]}`);
} Try / catch
try {
await addRepoToGroup(project, groupPath, registryName);
} catch (err) {
if (String(err.message).includes('is already mapped to')) {
logger.warn(`group path ${groupPath} already claimed; skipping`);
return;
}
throw err;
} Prevention
- Load and inspect group.yaml before adding mappings.
- Treat 'already mapped to same name' (returns false) as success in idempotent retry loops.
- Keep group.yaml under source control/review to catch manual edits.
When it happens
Trigger: Calling addRepoToGroup(project, groupPath, registryName) when loadGroupConfig already contains config.repos[groupPath] set to a registry name different from the one passed in.
Common situations: Re-registering a repo under a new registry name after it was renamed; two projects in the same group claim the same relative group path; stale group.yaml left behind by a previous run or manual edit.
Related errors
- must not contain backticks
- must not end with "/" or "."
- must not contain consecutive slashes
- must not contain "@{"
- must not contain hidden, trailing-dot, or .lock path compone
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08).
Data as JSON: /api/errors/42c77a6614db1992.
Report an issue: GitHub.