{"record":{"id":"d8dfdf4f32e5920f","repo":"eyaltoledano/claude-task-master","slug":"tagobj-must-be-a-valid-object","errorCode":null,"errorMessage":"tagObj must be a valid object","messagePattern":"tagObj must be a valid object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/utils.js","lineNumber":1910,"sourceCode":"\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn flattened;\n}\n\n/**\n * Ensures the tag object has a metadata object with created/updated timestamps.\n * @param {Object} tagObj - The tag object (e.g., data['master'])\n * @param {Object} [opts] - Optional fields (e.g., description, skipUpdate)\n * @param {string} [opts.description] - Description for the tag\n * @param {boolean} [opts.skipUpdate] - If true, don't update the 'updated' timestamp\n * @returns {Object} The updated tag object (for chaining)\n */\nfunction ensureTagMetadata(tagObj, opts = {}) {\n\tif (!tagObj || typeof tagObj !== 'object') {\n\t\tthrow new Error('tagObj must be a valid object');\n\t}\n\n\tconst now = new Date().toISOString();\n\n\tif (!tagObj.metadata) {\n\t\t// Create new metadata object\n\t\ttagObj.metadata = {\n\t\t\tcreated: now,\n\t\t\tupdated: now,\n\t\t\t...(opts.description ? { description: opts.description } : {})\n\t\t};\n\t} else {\n\t\t// Ensure existing metadata has required fields\n\t\tif (!tagObj.metadata.created) {\n\t\t\ttagObj.metadata.created = now;\n\t\t}\n\n\t\t// Update timestamp unless explicitly skipped","sourceCodeStart":1892,"sourceCodeEnd":1928,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/utils.js#L1892-L1928","documentation":"ensureTagMetadata() validates that its first argument is a non-null object before attaching metadata like 'updated' timestamps to a tag. This library throws when tagObj is null, undefined, or a non-object (string, number, etc.), because the function mutates and returns the tag object and cannot operate on anything else.","triggerScenarios":"Calling ensureTagMetadata(null), ensureTagMetadata(undefined), or passing a primitive such as a tag name string instead of the tag object, e.g. ensureTagMetadata(tag.name, opts) or passing a result of a lookup that returned null/undefined.","commonSituations":"A tag lookup (e.g. tasks data[tag]) returned undefined because the tag does not exist in tasks.json; refactored code accidentally passes the tag name instead of the tag object; JSON parsing produced null.","solutions":["Confirm the variable passed is the tag object, not the tag name string","Check that the tag exists before calling: const tag = data.tags[tag]; if (!tag) create it first","Add a guard before the call: if (tag && typeof tag === 'object') ensureTagMetadata(tag, opts)","Log the value and its typeof to find where it became null/undefined"],"exampleFix":"// before\nensureTagMetadata(data.tags[tagName], { description: 'My tag' });\n// after\nif (!data.tags[tagName]) throw new Error(`Tag '${tagName}' not found`);\nensureTagMetadata(data.tags[tagName], { description: 'My tag' });","handlingStrategy":"validation","validationCode":"if (!tagObj || typeof tagObj !== 'object') {\n  throw new TypeError(`ensureTagMetadata expects an object, got ${tagObj === null ? 'null' : typeof tagObj}`);\n}\nensureTagMetadata(tagObj, { skipUpdate: true });","typeGuard":"function isTagObject(v) {\n  return v !== null && typeof v === 'object' && typeof v.name === 'string';\n}","tryCatchPattern":"try {\n  ensureTagMetadata(tagObj, opts);\n} catch (err) {\n  if (err.message === 'tagObj must be a valid object') {\n    console.error('Tag lookup failed; check the tag exists in tasks.json', { received: tagObj });\n    return;\n  }\n  throw err;\n}","preventionTips":["Always pass the tag object, never the tag name string","Look up tags with a null check: data.tags[tag] may be undefined","Validate lookups with typeof before mutating","Unit-test tag helpers with missing/invalid inputs"],"tags":["argument-validation","tag-metadata","type-error"],"backgroundTag":"invalid-argument-type","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}