{"record":{"id":"4ea5d491de8ae08f","repo":"hcengineering/platform","slug":"object-presenter-not-found-for-class-class-pr","errorCode":null,"errorMessage":"object presenter not found for class=${_class}, preserve key ${JSON.stringify(preserveKey)}","messagePattern":"object presenter not found for class=(.+?), preserve key (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/view-resources/src/utils.ts","lineNumber":464,"sourceCode":"): Promise<AttributeModel> {\n  if (key.presenter !== undefined) {\n    const { presenter, label, sortingKey } = key\n    return {\n      key: key.key ?? '',\n      sortingKey: sortingKey ?? '',\n      _class,\n      label: label as IntlString,\n      presenter: typeof presenter === 'string' ? await getResource(presenter) : presenter,\n      props: preserveKey.props,\n      displayProps: preserveKey.displayProps,\n      collectionAttr: isCollectionAttr,\n      isLookup: false\n    }\n  }\n  if (key.key.length === 0) {\n    const p = await getObjectPresenter(client, _class, preserveKey, isCollectionAttr)\n    if (p === undefined) {\n      throw new Error(`object presenter not found for class=${_class}, preserve key ${JSON.stringify(preserveKey)}`)\n    }\n    return p\n  } else {\n    if (key.key.startsWith('$lookup')) {\n      if (lookup === undefined) {\n        throw new Error(`lookup class does not provided for ${key.key}`)\n      }\n      return await getLookupPresenter(client, _class, key, preserveKey, lookup)\n    }\n    return await getAttributePresenter(client, _class, key.key, preserveKey, undefined, _category)\n  }\n}\n\nfunction getKeyLookup<T extends Doc> (\n  hierarchy: Hierarchy,\n  _class: Ref<Class<T>>,\n  key: string,\n  lookup: Lookup<T>,","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/view-resources/src/utils.ts#L446-L482","documentation":"getPresenter falls back to getObjectPresenter to render a whole object when the key resolves to an empty key (an object-level presenter, e.g. for a lookup reference cell). It throws when no object presenter is registered for the given class. Like the attribute-presenter error, it signals a missing UI registration for that class.","triggerScenarios":"Rendering a reference/lookup column (or any key where key.key.length === 0) for a class that has no object presenter registered via getObjectPresenter registry.","commonSituations":"Custom/derived classes without a default presenter; lookup keys ($lookup...) used where the target class lacks a presenter; plugin with the object presenter not loaded; class renamed/refactored leaving the registry stale.","solutions":["Register a default object presenter for the class (view.component.ObjectPresenter per-class registration).","Verify the class id and preserveKey; ensure the lookup provides the correct lookup class.","Ensure the contributing plugin is installed/loaded.","Provide an explicit presenter/component for the cell instead of relying on defaults."],"exampleFix":"// before\nconst p = await getPresenter(client, myCustomClass, key)\n// after\nsetObjectPresenter(myCustomClass, myPlugin.component.MyCardPresenter) // register first\nconst p = await getPresenter(client, myCustomClass, key)","handlingStrategy":"fallback","validationCode":"const p = await getObjectPresenter(client, _class) ?? defaultObjectPresenter","typeGuard":"function hasObjectPresenter(cls: Ref<Class<Doc>>): boolean { return getObjectPresenterSync(cls) !== undefined }","tryCatchPattern":"try { return await getPresenter(client, _class, key) } catch { return genericObjectPresenter }","preventionTips":["Register default object presenters for all custom classes","Verify lookup target classes have presenters","Include presenter plugins in every deployment","Snapshot-test presenters for key classes"],"tags":["presenter","configuration","ui","lookup"],"backgroundTag":"missing-presenter-registration","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}