{"record":{"id":"cdf7dbc53d87266b","repo":"eyaltoledano/claude-task-master","slug":"source-tag-sourcetag-not-found-or-has-no-tasks","errorCode":null,"errorMessage":"Source tag ${sourceTag} not found or has no tasks","messagePattern":"Source tag (.+?) not found or has no tasks","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts","lineNumber":803,"sourceCode":"\t\t\t\t\tthrow new Error(`Tag ${oldTag} not found in standard format`);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tif (error.code === 'ENOENT') {\n\t\t\t\tthrow new Error(`Tag ${oldTag} not found - file doesn't exist`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Copy a tag within the single tasks.json file\n\t */\n\tasync copyTag(sourceTag: string, targetTag: string): Promise<void> {\n\t\tconst tasks = await this.loadTasks(sourceTag);\n\n\t\tif (tasks.length === 0) {\n\t\t\tthrow new Error(`Source tag ${sourceTag} not found or has no tasks`);\n\t\t}\n\n\t\tawait this.saveTasks(tasks, targetTag);\n\t}\n\n\t/**\n\t * Get all tags with detailed statistics including task counts\n\t * For file storage, reads tags from tasks.json and calculates statistics\n\t */\n\tasync getTagsWithStats(): Promise<{\n\t\ttags: Array<{\n\t\t\tname: string;\n\t\t\tisCurrent: boolean;\n\t\t\ttaskCount: number;\n\t\t\tcompletedTasks: number;\n\t\t\tstatusBreakdown: Record<string, number>;\n\t\t\tsubtaskCounts?: {\n\t\t\t\ttotalSubtasks: number;","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts#L785-L821","documentation":"FileStorage.copyTag throws this when loading the source tag yields zero tasks, meaning either the source tag does not exist in the tasks.json file or it exists but contains no task entries. The library refuses to copy an empty/missing tag to a target.","triggerScenarios":"Calling copyTag(sourceTag, targetTag) where sourceTag has no tasks in tasks.json — either the tag key is absent or it maps to an empty task list.","commonSituations":"Copying from a tag with a typo; copying a freshly created empty tag; source tag removed by a concurrent edit; running copyTag against the wrong project directory.","solutions":["Check the source tag exists and has tasks via getTasks(sourceTag) before copying","Fix the source tag name spelling","Create/populate the source tag with tasks first","If copying an empty tag is intentional, save tasks to targetTag directly instead of copyTag"],"exampleFix":"// before\nawait storage.copyTag('v1', 'v1-backup');\n// after\nconst tasks = await storage.getTasks('v1');\nif (tasks.length === 0) throw new Error('Nothing to copy: tag v1 has no tasks');\nawait storage.copyTag('v1', 'v1-backup');","handlingStrategy":"validation","validationCode":"const tasks = await storage.getTasks(sourceTag);\nif (tasks.length === 0) {\n  throw new Error(`copyTag aborted: '${sourceTag}' missing or empty`);\n}\nawait storage.copyTag(sourceTag, targetTag);","typeGuard":null,"tryCatchPattern":"try {\n  await storage.copyTag(sourceTag, targetTag);\n} catch (e) {\n  if (/Source tag .* not found or has no tasks/.test(e.message)) {\n    console.warn(`Nothing to copy from '${sourceTag}'`);\n    return;\n  }\n  throw e;\n}","preventionTips":["Check getTasks(sourceTag).length > 0 before copyTag","Verify tag spelling against listTags() output","Guard against copying freshly created empty tags","Log available tags in error paths to speed diagnosis"],"tags":["file-system","tags","not-found"],"backgroundTag":"tag-not-found","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}