{"record":{"id":"b6e4a612573fdbec","repo":"hcengineering/platform","slug":"domain-not-found-class","errorCode":null,"errorMessage":"domain not found: ${_class} ","messagePattern":"domain not found: (.+?) ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"foundations/core/packages/core/src/hierarchy.ts","lineNumber":236,"sourceCode":"    const data = this.classifiers.get(_class)\n    if (data === undefined) {\n      throw new Error('class not found: ' + _class)\n    }\n    return data\n  }\n\n  getInterface (_interface: Ref<Interface<Doc>>): Interface<Doc> {\n    const data = this.classifiers.get(_interface)\n    if (data === undefined || !this.isInterface(data)) {\n      throw new Error('interface not found: ' + _interface)\n    }\n    return data\n  }\n\n  getDomain (_class: Ref<Class<Obj>>): Domain {\n    const domain = this.findDomain(_class)\n    if (domain === undefined) {\n      throw new Error(`domain not found: ${_class} `)\n    }\n    return domain\n  }\n\n  public findDomain (_class: Ref<Class<Doc>>): Domain | undefined {\n    const klazz = this.findClass(_class)\n    if (klazz === undefined) return\n    if (klazz.domain !== undefined) {\n      return klazz.domain\n    }\n\n    let _klazz: Class<Doc> | undefined = klazz\n    while (_klazz.extends !== undefined) {\n      _klazz = this.findClass(_klazz.extends)\n      if (_klazz === undefined) return\n      if (_klazz.domain !== undefined) {\n        // Cache for next requests\n        klazz.domain = _klazz.domain","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/core/src/hierarchy.ts#L218-L254","documentation":"Hierarchy.getDomain determines which model domain (e.g. model, task, contact) a class belongs to by walking ancestors via findDomain. If no ancestor has a registered domain, it throws 'domain not found'. It indicates the class (or its ancestors) is not registered in the hierarchy, so its domain cannot be inferred.","triggerScenarios":"Calling getDomain/domain/baseDomain with an unregistered class ref; calling during fixMixinForeignAttributes or updateField before the class model tx is applied; typos in class refs.","commonSituations":"Upgrade scripts running before model txes are pushed; client-side hierarchy missing the plugin model; a new class created without adding it to a domain's hierarchy ancestors.","solutions":["Apply the class's model tx to the hierarchy before calling getDomain","Confirm the class ref is spelled correctly and its plugin model is loaded","Use findDomain(...) !== undefined as a guard when the class may be unregistered","Check the class derives from an ancestor that carries the domain registration"],"exampleFix":"// before\nconst domain = hierarchy.getDomain(myClass)\n// after\nconst domain = hierarchy.findDomain(myClass)\nif (domain === undefined) throw new Error(`Class ${myClass} is not registered in hierarchy`)\n// then use domain\nreturn domain","handlingStrategy":"validation","validationCode":"const domain = hierarchy.findDomain(_class)\nif (domain === undefined) {\n  throw new Error(`No domain registered for class ${String(_class)}`)\n}\n// safe to use domain","typeGuard":"function hasDomain(h: Hierarchy, c: Ref<Class<Doc>>): boolean {\n  return h.findDomain(c) !== undefined\n}","tryCatchPattern":"let domain: Domain\ntry {\n  domain = hierarchy.getDomain(_class)\n} catch (err) {\n  console.error(`Cannot resolve domain for ${String(_class)}`, err)\n  throw err\n}","preventionTips":["Ensure every custom class derives from an ancestor carrying a domain","Run getDomain-dependent code only after full model sync/upgrades","Prefer findDomain + explicit undefined handling in library-like code","Check class refs against the installed plugin set"],"tags":["hierarchy","domain","missing-classifier"],"backgroundTag":"classifier-not-registered","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}