{"record":{"id":"1375e3ef175fb1c9","repo":"hcengineering/platform","slug":"descendants-not-found-class","errorCode":null,"errorMessage":"descendants not found: ${_class}","messagePattern":"descendants not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"foundations/core/packages/core/src/hierarchy.ts","lineNumber":390,"sourceCode":"   */\n  private isExtends<T extends Doc>(extendsOrImplements: Ref<Interface<Doc>>[], from: Ref<Interface<T>>): boolean {\n    const result: Ref<Interface<Doc>>[] = []\n    const toVisit = [...extendsOrImplements]\n    while (toVisit.length > 0) {\n      const ref = toVisit.shift() as Ref<Interface<Doc>>\n      if (ref === from) {\n        return true\n      }\n      addIf(result, ref)\n      toVisit.push(...this.ancestorsOf(ref))\n    }\n    return false\n  }\n\n  getDescendants<T extends Obj>(_class: Ref<Class<T>>): Ref<Class<Obj>>[] {\n    const data = this.descendants.get(_class)\n    if (data === undefined) {\n      throw new Error('descendants not found: ' + _class)\n    }\n    return data\n  }\n\n  private updateDescendant (_class: Ref<Classifier>, add = true): void {\n    let hierarchy: Ref<Classifier>[] = []\n\n    try {\n      hierarchy = this.getAncestors(_class)\n    } catch (err) {\n      if (add) {\n        throw err\n      }\n    }\n\n    for (const cls of hierarchy) {\n      const list = this.descendants.get(cls)\n      if (list === undefined) {","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/core/src/hierarchy.ts#L372-L408","documentation":"Hierarchy.getDescendants returns the precomputed list of descendant classes for a registered classifier from the internal descendants map. The map is populated during hierarchy construction (updateDescendant). If the class was never added to the hierarchy, no descendant entry exists and this Error is thrown.","triggerScenarios":"Calling getDescendants (directly or via classes, descendants, isClassIndexable, getFullTextIndexableAttributes) with a class ref whose hierarchy.addedTx was never processed; calling before initial model sync completes.","commonSituations":"Querying descendants during startup before the model transaction batch finishes; plugin model not installed; constructing a fresh Hierarchy in tests without replaying all classifier txes.","solutions":["Ensure all model txes (including the class definition) have been applied via hierarchy.addedTx before querying descendants","Verify the class ref belongs to an installed model package","For optional classes, filter with hierarchy.findClass first or wrap in try/catch","Check initialization order so descendants queries happen after hierarchy hydration"],"exampleFix":"// before\nconst sub = hierarchy.getDescendants(core.class.Doc)\n// after\nif (hierarchy.findClass(core.class.Doc) === undefined) {\n  throw new Error('Hierarchy not initialized - model txes missing')\n}\nconst sub = hierarchy.getDescendants(core.class.Doc)","handlingStrategy":"validation","validationCode":"if (hierarchy.findClass(_class) === undefined) {\n  throw new Error(`Hierarchy not initialized for ${String(_class)} - missing model tx`)\n}\nconst descendants = hierarchy.getDescendants(_class)","typeGuard":"function hasDescendants(h: Hierarchy, c: Ref<Class<Obj>>): boolean {\n  return h.findClass(c) !== undefined\n}","tryCatchPattern":"let subtypes: Ref<Class<Obj>>[]\ntry {\n  subtypes = hierarchy.getDescendants(_class)\n} catch (err) {\n  console.error(`Descendants unavailable for ${String(_class)}; hierarchy not hydrated`, err)\n  throw err\n}","preventionTips":["Initialize hierarchy from the complete model tx batch before querying","Sequence startup so descendant-dependent features run after model hydration","Use findClass as a cheap existence probe first","Load all plugin models, not just the ones in direct use"],"tags":["hierarchy","descendants","missing-classifier","initialization-order"],"backgroundTag":"classifier-not-registered","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}