hcengineering/platform · error

category is not found in model

Error message

category is not found in model

What it means

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.

Source

Thrown at plugins/task/src/utils.ts:204

 */
export async function createProjectType (
  client: TxOperations,
  data: ProjectData,
  tasks: TaskTypeWithFactory[],
  _id: Ref<ProjectType>
): Promise<Ref<ProjectType>> {
  const current = await client.findOne(task.class.ProjectType, { _id })
  if (current !== undefined) {
    return current._id
  }

  const _tasks: Ref<TaskType>[] = []
  const tasksData = new Map<Ref<TaskType>, Data<TaskType>>()
  const _statues = new Set<Ref<Status>>()

  const categoryObj = client.getModel().findObject(data.descriptor)
  if (categoryObj === undefined) {
    throw new Error('category is not found in model')
  }

  await createTaskTypes(tasks, _id, client, _statues, tasksData, _tasks, false)

  const baseClassClass = client.getHierarchy().getClass(categoryObj.baseClass)

  // NOTE: it is important for this id to be consistent when re-creating the same
  // project type with the same id as it will happen during every migration if type is created by the system
  const targetProjectClassId = `${_id}:type:mixin` as Ref<Class<Doc>>
  const tmpl = await client.createDoc(
    task.class.ProjectType,
    core.space.Model,
    {
      description: data.description,
      shortDescription: data.shortDescription,
      descriptor: data.descriptor,
      roles: 0,
      tasks: _tasks,

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Confirm the plugin exporting the descriptor is loaded into the client model before calling createProjectType
  2. Use the exported descriptor constant from the plugin instead of a hand-written string id
  3. Dump client.getModel().findObject(data.descriptor) / list model objects of the descriptor class to verify presence and exact id
  4. If descriptors changed across versions, migrate references to the new descriptor ids

Example fix

// before
await createProjectTypeWithTaskTypes(client, { descriptor: 'task:desc:Kanban' as Ref<ProjectTypeDescriptor>, ... })
// after
const descriptor = taskPlugin.descriptors.Kanban
if (client.getModel().findObject(descriptor) === undefined) {
  throw new Error('Descriptor plugin not loaded: ' + descriptor)
}
await createProjectTypeWithTaskTypes(client, { descriptor, ... })
Defensive patterns

Strategy: validation

Validate before calling

function canCreateProjectType (client: TxOperations, data: Data<ProjectType>): boolean {
  return client.getModel().findObject(data.descriptor) !== undefined
}
// before createProjectType: if (!canCreateProjectType(client, data)) throw new Error('Descriptor plugin not loaded: ' + data.descriptor)

Type guard

function isDescriptorInModel (client: TxOperations, ref: Ref<ProjectTypeDescriptor>): boolean {
  return client.getModel().findObject(ref) !== undefined
}

Try / catch

try {
  await createProjectTypeWithTaskTypes(client, data, tasks)
} catch (err) {
  if (err instanceof Error && err.message.includes('category is not found in model')) {
    console.error('Project type descriptor missing:', data.descriptor, '- check plugin configuration')
  }
  throw err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/ed0e8427718a6c72. Report an issue: GitHub.