{"record":{"id":"d2e8d14dc236af5d","repo":"eyaltoledano/claude-task-master","slug":"tag-newname-already-exists","errorCode":null,"errorMessage":"Tag \"${newName}\" already exists","messagePattern":"Tag \"(.+?)\" already exists","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/tag-management.js","lineNumber":1001,"sourceCode":"\t\tlogFn.info(`Renaming tag from \"${oldName}\" to \"${newName}\"`);\n\n\t\t// Read current tasks data\n\t\tconst data = readJSON(tasksPath, projectRoot);\n\t\tif (!data) {\n\t\t\tthrow new Error(`Could not read tasks file at ${tasksPath}`);\n\t\t}\n\n\t\t// Use raw tagged data for tag operations\n\t\tconst rawData = data._rawTaggedData || data;\n\n\t\t// Check if old tag exists\n\t\tif (!rawData[oldName]) {\n\t\t\tthrow new Error(`Tag \"${oldName}\" does not exist`);\n\t\t}\n\n\t\t// Check if new tag name already exists\n\t\tif (rawData[newName]) {\n\t\t\tthrow new Error(`Tag \"${newName}\" already exists`);\n\t\t}\n\n\t\t// Get current tag to check if we're renaming the active tag\n\t\tconst currentTag = getCurrentTag(projectRoot);\n\t\tconst isCurrentTag = currentTag === oldName;\n\n\t\t// Rename the tag by copying data and deleting old\n\t\trawData[newName] = { ...rawData[oldName] };\n\n\t\t// Update metadata if it exists\n\t\tif (rawData[newName].metadata) {\n\t\t\trawData[newName].metadata.renamed = {\n\t\t\t\tfrom: oldName,\n\t\t\t\tdate: new Date().toISOString()\n\t\t\t};\n\t\t}\n\n\t\tdelete rawData[oldName];","sourceCodeStart":983,"sourceCodeEnd":1019,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/tag-management.js#L983-L1019","documentation":"renameTag() refuses to rename to a tag name that already exists in the tagged data, since two tags cannot share one key. This prevents silently overwriting an existing tag's tasks. Delete the conflicting tag or choose another name.","triggerScenarios":"Calling renameTag(tasksPath, 'a', 'b') when a tag 'b' already exists; renaming a tag back to a name it previously held; bulk rename scripts producing colliding targets.","commonSituations":"Retry after a partially completed rename left both names present; users toggling between two names ('todo' <-> 'doing') without deleting; auto-generated names colliding with existing tags.","solutions":["Choose a unique target name that does not already exist in tasks.json","Delete or rename the existing conflicting tag first (deleteTag / another renameTag call)","Guard before calling: check the target key is absent in the parsed tasks.json data","If data is left over from a failed rename, clean up the duplicate tag manually in tasks.json"],"exampleFix":"// before\nawait renameTag(tasksPath, 'wip', 'in-progress'); // already exists\n// after\nconst data = JSON.parse(fs.readFileSync(tasksPath, 'utf8'));\nif (data['in-progress']) await deleteTag(tasksPath, 'in-progress');\nawait renameTag(tasksPath, 'wip', 'in-progress');","handlingStrategy":"validation","validationCode":"const data = JSON.parse(require('fs').readFileSync(tasksPath, 'utf8'));\nif (Object.prototype.hasOwnProperty.call(data, newName)) {\n  throw new Error(`Target tag \"${newName}\" already exists; choose another name or delete it first`);\n}","typeGuard":"function tagIsFree(tasksData, name) {\n  return typeof name === 'string' && !Object.prototype.hasOwnProperty.call(tasksData, name);\n}","tryCatchPattern":"try {\n  await renameTag(tasksPath, oldName, newName);\n} catch (err) {\n  if (err.message.includes('already exists')) {\n    console.error(`Tag \"${newName}\" is taken — pick a unique name or delete the existing tag`);\n    return;\n  }\n  throw err;\n}","preventionTips":["Check target-name availability before renaming, especially in automated flows","Generate unique names (suffix with date/timestamp) for scripted renames","Clean up partial state if a previous rename/copy failed midway","Delete unwanted tags with deleteTag before reusing their names"],"tags":["tag-management","conflict","uniqueness"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}