{"record":{"id":"ce14cfc4e933f4e3","repo":"hcengineering/platform","slug":"hierarchy-is-not-defined","errorCode":null,"errorMessage":"Hierarchy is not defined","messagePattern":"Hierarchy is not defined","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"foundations/core/packages/api-client/src/rest/adapter.ts","lineNumber":85,"sourceCode":"  async findOne<T extends Doc>(\n    _class: Ref<Class<T>>,\n    query: DocumentQuery<T>,\n    options?: FindOptions<T>\n  ): Promise<WithLookup<T> | undefined> {\n    return await this.client.findOne(_class, query, options)\n  }\n\n  async searchFulltext (query: SearchQuery, options: SearchOptions): Promise<SearchResult> {\n    return await this.client.searchFulltext(query, options)\n  }\n\n  async close (): Promise<void> {\n    // No ned to close the REST client\n  }\n\n  getHierarchy (): Hierarchy {\n    if (this.hierarchy === undefined) {\n      throw new Error('Hierarchy is not defined')\n    }\n    return this.hierarchy\n  }\n\n  getModel (): ModelDb {\n    if (this.model === undefined) {\n      throw new Error('Model is not defined')\n    }\n    return this.model\n  }\n}\n","sourceCodeStart":67,"sourceCodeEnd":97,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/api-client/src/rest/adapter.ts#L67-L97","documentation":"The REST client adapter lazily receives a Hierarchy (model metadata) after initialization; getHierarchy throws 'Hierarchy is not defined' when it is called before the adapter has been initialized/connected with the model. The hierarchy is required for object-class operations.","triggerScenarios":"Calling client.getHierarchy() (or any API relying on it) on a RestClientAdapter before its hierarchy was assigned during init/connect; constructing the adapter manually and skipping the initialization step.","commonSituations":"Using the REST adapter directly instead of via the connect() factory, calling methods before an awaited init completes, race where an async setup assigns hierarchy after first use.","solutions":["Ensure the adapter is fully initialized (await connect / the init that assigns hierarchy) before calling getHierarchy.","Use the high-level client factory (connect / getClient) instead of instantiating the REST adapter manually.","Await all setup promises before issuing the first model-dependent call."],"exampleFix":"// before\nconst adapter = new RestClientAdapter(url, workspace, token)\nconst h = adapter.getHierarchy()\n// after\nconst client = await connect(url, { workspace, token }) // performs full init\nconst h = client.getHierarchy()","handlingStrategy":"try-catch","validationCode":"// Only valid after awaiting the client factory\nconst client = await connect(url, { workspace, token }) // guarantees hierarchy assignment\nif (client.getHierarchy == null) throw new Error('adapter does not expose a hierarchy')","typeGuard":"function hasHierarchy(c: unknown): c is { getHierarchy: () => Hierarchy } {\n  return typeof c === 'object' && c !== null && typeof (c as any).getHierarchy === 'function'\n}","tryCatchPattern":"try {\n  const hierarchy = adapter.getHierarchy()\n} catch (e) {\n  if (e instanceof Error && e.message === 'Hierarchy is not defined') {\n    throw new Error('Adapter used before initialization — await connect()/init before model operations')\n  }\n  throw e\n}","preventionTips":["Always create clients via the connect()/factory API rather than constructing adapters directly","Await initialization before any model/hierarchy access; never call in module top-level code","In tests, reuse the real initialization path instead of partial mocks"],"tags":["initialization","lifecycle","typescript"],"backgroundTag":"client-not-initialized","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}