{"record":{"id":"20103f63fe68cfa5","repo":"eyaltoledano/claude-task-master","slug":"tag-name-is-required-and-must-be-a-string","errorCode":null,"errorMessage":"Tag name is required and must be a string","messagePattern":"Tag name is required and must be a string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/tag-management.js","lineNumber":86,"sourceCode":"\t});\n\n\t// If remote handled it, return the result\n\tif (remoteResult) {\n\t\tif (!remoteResult.success) {\n\t\t\tthrow new Error(remoteResult.message || 'Remote tag creation failed');\n\t\t}\n\t\tif (outputFormat === 'json') {\n\t\t\treturn remoteResult;\n\t\t}\n\t\t// For text output, the bridge already displayed the message\n\t\treturn remoteResult;\n\t}\n\n\t// Otherwise, continue with file-based logic below\n\ttry {\n\t\t// Validate tag name\n\t\tif (!tagName || typeof tagName !== 'string') {\n\t\t\tthrow new Error('Tag name is required and must be a string');\n\t\t}\n\n\t\t// Validate tag name format (alphanumeric, hyphens, underscores only)\n\t\tif (!/^[a-zA-Z0-9_-]+$/.test(tagName)) {\n\t\t\tthrow new Error(\n\t\t\t\t'Tag name can only contain letters, numbers, hyphens, and underscores'\n\t\t\t);\n\t\t}\n\n\t\t// Reserved tag names\n\t\tconst reservedNames = ['master', 'main', 'default'];\n\t\tif (reservedNames.includes(tagName.toLowerCase())) {\n\t\t\tthrow new Error(`\"${tagName}\" is a reserved tag name`);\n\t\t}\n\n\t\tlogFn.info(`Creating new tag: ${tagName}`);\n\n\t\t// Read current tasks data","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/tag-management.js#L68-L104","documentation":"In the file-based branch of createTag, the tag name is validated for presence and type before any file operations. A missing, null, or non-string tagName throws this error. It is the first line of defense for tag-name input validation.","triggerScenarios":"Calling createTag(undefined, ...) or createTag(null, ...), passing a non-string (number/object) tagName, or CLI/MCP callers forwarding an empty --name flag.","commonSituations":"Scripted automation passing variables that resolve to undefined; Commander option omitted so name is undefined; JSON payloads to the MCP tool missing the tagName field.","solutions":["Pass a non-empty string as tagName, e.g. createTag(tasksPath, 'feature-x', options)","Validate CLI flags: ensure --name is provided on 'task-master add-tag'","In scripts, default/normalize the name: const name = String(rawName || '').trim()"],"exampleFix":"// before\nawait createTag(tasksPath, opts.tag, {}); // opts.tag undefined\n// after\nif (!opts.tag) throw new Error('--name is required');\nawait createTag(tasksPath, String(opts.tag), {});","handlingStrategy":"validation","validationCode":"if (typeof tagName !== 'string' || tagName.trim() === '') {\n  throw new Error('tagName must be a non-empty string');\n}","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await createTag(tasksPath, tagName, {});\n} catch (err) {\n  if (err.message === 'Tag name is required and must be a string') {\n    console.error('Provide --name, e.g. task-master add-tag --name my-tag');\n  } else throw err;\n}","preventionTips":["Make --name required in CLI wrappers and MCP tool schemas","Coerce/trim user input before passing it through","In scripts, assert arguments early with a small validation helper","Give CLI options explicit defaults or fail fast with usage text"],"tags":["validation","arguments","tagging"],"backgroundTag":"missing-required-argument","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}