hcengineering/platform · error

presenter not found for ${_class}

Error message

presenter not found for ${_class}

What it means

When resolving the presenter for an association's end class, the code looks for a classHierarchyMixin implementing view.mixin.CollectionPresenter with a defined `presenter`. If the class hierarchy provides no presenter mixin, it logs and throws.

Source

Thrown at plugins/view-resources/src/utils.ts:712

        key: key.key,
        sortingKey: '',
        _class,
        label: getEmbeddedLabel(name + ' › ' + subFieldParts.join('.')),
        presenter,
        props: key.props,
        displayProps: key.displayProps,
        collectionAttr: false,
        isLookup: true
      }
    }
  }

  const presenterMixin = hierarchy.classHierarchyMixin(_class, view.mixin.CollectionPresenter)
  if (presenterMixin?.presenter === undefined) {
    console.error(
      `object presenter not found for class=${_class}, mixin=${view.mixin.ObjectPresenter}, preserve key ${JSON.stringify(key)}`
    )
    throw new Error('presenter not found for ' + _class)
  }
  const presenter = await getResource(presenterMixin.presenter)

  return {
    key: key.key,
    sortingKey: '',
    _class,
    label: getEmbeddedLabel(name),
    presenter,
    props: key.props,
    displayProps: key.displayProps,
    collectionAttr: false,
    isLookup: true
  }
}

export async function deleteObject (client: TxOperations, object: Doc): Promise<void> {
  const currentAcc = getCurrentAccount()

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Add view.mixin.CollectionPresenter with a presenter resource to the target class definition
  2. Register the presenter resource so getResource(presenterMixin.presenter) resolves
  3. Check the mixin is applied via classHierarchyMixin on all subclasses of the displayed class

Example fix

// before
class MyDoc extends Doc {} // no presenter mixin
// after
@Model('my::MyDoc', Doc)
export class MyDoc extends Doc {}
hierarchy.addMixin(MyDoc, view.mixin.CollectionPresenter, { presenter: myPresenterResource })
Defensive patterns

Strategy: validation

Validate before calling

const hierarchy = client.getHierarchy()
const mixin = hierarchy.classHierarchyMixin(targetClass, view.mixin.CollectionPresenter)
if (mixin?.presenter === undefined) {
  throw new Error(`register CollectionPresenter for ${targetClass} first`)
}

Type guard

function hasCollectionPresenter(h: Hierarchy, _class: Ref<Class<Doc>>): boolean {
  return h.classHierarchyMixin(_class, view.mixin.CollectionPresenter)?.presenter !== undefined
}

Try / catch

try {
  return await model(client, _class, keys)
} catch (err) {
  if (String(err.message).startsWith('presenter not found')) {
    console.error('add view.mixin.CollectionPresenter to', _class)
    return []
  }
  throw err
}

Prevention

When it happens

Trigger: Building a model for an $associations relation whose target class does not register a CollectionPresenter mixin (or the mixin exists but presenter is undefined).

Common situations: Custom domain class added without declaring view.mixin.CollectionPresenter in its class definition; typo in mixin resource id; class hierarchy not loaded for the target class.

Related errors


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