{"record":{"id":"ed0e8427718a6c72","repo":"hcengineering/platform","slug":"category-is-not-found-in-model","errorCode":null,"errorMessage":"category is not found in model","messagePattern":"category is not found in model","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/task/src/utils.ts","lineNumber":204,"sourceCode":" */\nexport async function createProjectType (\n  client: TxOperations,\n  data: ProjectData,\n  tasks: TaskTypeWithFactory[],\n  _id: Ref<ProjectType>\n): Promise<Ref<ProjectType>> {\n  const current = await client.findOne(task.class.ProjectType, { _id })\n  if (current !== undefined) {\n    return current._id\n  }\n\n  const _tasks: Ref<TaskType>[] = []\n  const tasksData = new Map<Ref<TaskType>, Data<TaskType>>()\n  const _statues = new Set<Ref<Status>>()\n\n  const categoryObj = client.getModel().findObject(data.descriptor)\n  if (categoryObj === undefined) {\n    throw new Error('category is not found in model')\n  }\n\n  await createTaskTypes(tasks, _id, client, _statues, tasksData, _tasks, false)\n\n  const baseClassClass = client.getHierarchy().getClass(categoryObj.baseClass)\n\n  // NOTE: it is important for this id to be consistent when re-creating the same\n  // project type with the same id as it will happen during every migration if type is created by the system\n  const targetProjectClassId = `${_id}:type:mixin` as Ref<Class<Doc>>\n  const tmpl = await client.createDoc(\n    task.class.ProjectType,\n    core.space.Model,\n    {\n      description: data.description,\n      shortDescription: data.shortDescription,\n      descriptor: data.descriptor,\n      roles: 0,\n      tasks: _tasks,","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/task/src/utils.ts#L186-L222","documentation":"createProjectType builds a ProjectType from a descriptor reference; it looks up data.descriptor in the model with findObject and throws this error when the descriptor (a ProjectTypeDescriptor / category object) is absent. Like the space-type counterpart, it guards against creating project types whose descriptor plugin is not part of the loaded model.","triggerScenarios":"Calling createProjectType (often via createProjectTypeWithTaskTypes) with a descriptor Ref not present in client.getModel() — missing plugin, wrong/renamed descriptor id, or model built from an incomplete plugin set.","commonSituations":"Custom project types referencing descriptors from a plugin removed in an upgrade; copy-pasted string ids instead of plugin exports; migrations running before all descriptor plugins are registered.","solutions":["Confirm the plugin exporting the descriptor is loaded into the client model before calling createProjectType","Use the exported descriptor constant from the plugin instead of a hand-written string id","Dump client.getModel().findObject(data.descriptor) / list model objects of the descriptor class to verify presence and exact id","If descriptors changed across versions, migrate references to the new descriptor ids"],"exampleFix":"// before\nawait createProjectTypeWithTaskTypes(client, { descriptor: 'task:desc:Kanban' as Ref<ProjectTypeDescriptor>, ... })\n// after\nconst descriptor = taskPlugin.descriptors.Kanban\nif (client.getModel().findObject(descriptor) === undefined) {\n  throw new Error('Descriptor plugin not loaded: ' + descriptor)\n}\nawait createProjectTypeWithTaskTypes(client, { descriptor, ... })","handlingStrategy":"validation","validationCode":"function canCreateProjectType (client: TxOperations, data: Data<ProjectType>): boolean {\n  return client.getModel().findObject(data.descriptor) !== undefined\n}\n// before createProjectType: if (!canCreateProjectType(client, data)) throw new Error('Descriptor plugin not loaded: ' + data.descriptor)","typeGuard":"function isDescriptorInModel (client: TxOperations, ref: Ref<ProjectTypeDescriptor>): boolean {\n  return client.getModel().findObject(ref) !== undefined\n}","tryCatchPattern":"try {\n  await createProjectTypeWithTaskTypes(client, data, tasks)\n} catch (err) {\n  if (err instanceof Error && err.message.includes('category is not found in model')) {\n    console.error('Project type descriptor missing:', data.descriptor, '- check plugin configuration')\n  }\n  throw err\n}","preventionTips":["Import descriptor ids from plugin exports rather than raw strings","Run a model completeness check in tests for all project types created in fixtures","Re-audit descriptor references after plugin renames/upgrades"],"tags":["model","plugin-configuration","descriptor"],"backgroundTag":"model-object-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}