eyaltoledano/claude-task-master · error
tagObj must be a valid object
Error message
tagObj must be a valid object
What it means
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.
Source
Thrown at scripts/modules/utils.js:1910
});
}
}
}
return flattened;
}
/**
* Ensures the tag object has a metadata object with created/updated timestamps.
* @param {Object} tagObj - The tag object (e.g., data['master'])
* @param {Object} [opts] - Optional fields (e.g., description, skipUpdate)
* @param {string} [opts.description] - Description for the tag
* @param {boolean} [opts.skipUpdate] - If true, don't update the 'updated' timestamp
* @returns {Object} The updated tag object (for chaining)
*/
function ensureTagMetadata(tagObj, opts = {}) {
if (!tagObj || typeof tagObj !== 'object') {
throw new Error('tagObj must be a valid object');
}
const now = new Date().toISOString();
if (!tagObj.metadata) {
// Create new metadata object
tagObj.metadata = {
created: now,
updated: now,
...(opts.description ? { description: opts.description } : {})
};
} else {
// Ensure existing metadata has required fields
if (!tagObj.metadata.created) {
tagObj.metadata.created = now;
}
// Update timestamp unless explicitly skippedView on GitHub (pinned to c0c98d367c)
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
Example fix
// before
ensureTagMetadata(data.tags[tagName], { description: 'My tag' });
// after
if (!data.tags[tagName]) throw new Error(`Tag '${tagName}' not found`);
ensureTagMetadata(data.tags[tagName], { description: 'My tag' }); Defensive patterns
Strategy: validation
Validate before calling
if (!tagObj || typeof tagObj !== 'object') {
throw new TypeError(`ensureTagMetadata expects an object, got ${tagObj === null ? 'null' : typeof tagObj}`);
}
ensureTagMetadata(tagObj, { skipUpdate: true }); Type guard
function isTagObject(v) {
return v !== null && typeof v === 'object' && typeof v.name === 'string';
} Try / catch
try {
ensureTagMetadata(tagObj, opts);
} catch (err) {
if (err.message === 'tagObj must be a valid object') {
console.error('Tag lookup failed; check the tag exists in tasks.json', { received: tagObj });
return;
}
throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- projectRoot is required for isGitRepository
- projectRoot is required for getCurrentBranch
- projectRoot is required for getLocalBranches
- projectRoot is required for getRemoteBranches
- projectRoot is required for getGitHubRepoInfo
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/d8dfdf4f32e5920f.
Report an issue: GitHub.