hcengineering/platform · error
Tag category not found
Error message
Tag category not found
What it means
findTagCategory searches existing tag categories for one whose tags list contains the given title (case-insensitive); if none matches and no default category was found, it throws 'Tag category not found'. It signals the caller asked to attach/lookup a tag in a category that does not exist in the target space/domain.
Source
Thrown at plugins/tags/src/index.ts:147
* @public
*/
export default tagsPlugin
/**
* @public
*/
export function findTagCategory (title: string, categories: TagCategory[]): Ref<TagCategory> {
let defaultCategory: TagCategory | undefined
for (const c of categories) {
if (c.default) {
defaultCategory = c
}
if (c.tags.findIndex((it) => it.toLowerCase() === title.toLowerCase()) !== -1) {
return c._id
}
}
if (defaultCategory === undefined) {
throw new Error('Tag category not found')
}
return defaultCategory._id
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Ensure default tag categories are created/seeded for the domain before calling findTagCategory
- Compare the title against existing category tags (client.findAll(tags.class.TagCategory)) to spot casing/spelling mismatches
- Create the category explicitly if it doesn't exist instead of relying on the default fallback
- Pass the exact title used when the category's tags were registered
Example fix
// before
const category = await findTagCategory(client, domain, 'Custum Tags') // typo
// after
const categories = await client.findAll(tags.class.TagCategory, { domain })
if (categories.length === 0) {
await createDefaultTagCategories(client, domain)
}
const category = await findTagCategory(client, domain, 'Custom Tags') Defensive patterns
Strategy: validation
Validate before calling
async function categoryExists (client: TxOperations, domain: string, title: string): Promise<boolean> {
const categories = await client.findAll(tags.class.TagCategory, { domain })
return categories.some((c) => c.tags.some((t) => t.toLowerCase() === title.toLowerCase()))
} Type guard
function findMatchingCategory (categories: TagCategory[], title: string): TagCategory | undefined {
return categories.find((c) => c.tags.some((t) => t.toLowerCase() === title.toLowerCase()))
} Try / catch
try {
const categoryId = await findTagCategory(client, domain, title)
} catch (err) {
if (err instanceof Error && err.message === 'Tag category not found') {
await seedDefaultTagCategories(client, domain)
return findTagCategory(client, domain, title)
}
throw err
} Prevention
- Seed default tag categories during workspace initialization
- Normalize titles (trim/case) before lookup
- Never hardcode category titles without verifying they exist in the target domain
When it happens
Trigger: Calling tag creation/lookup with a category title that doesn't match any tag on existing categories, in a domain where no default category has been created yet — e.g. first use before any category seeding, or a title typo/different language casing.
Common situations: Fresh workspace where default tag categories were never initialized; renamed category titles so the old title no longer matches; querying with a title from a different domain.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- core.status.ObjectNotFound
- Integration not found: ${JSON.stringify(integrationKey)}
- platform.status.ResourceNotFound
- Lead not found, _id: ${ref}
- No project type found
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4ef9b8dd185fe443.
Report an issue: GitHub.