hcengineering/platform · error

lookup class does not provided for ${key.key}

Error message

lookup class does not provided for ${key.key}

What it means

getPresenter builds the presenter model for a view key. When the key is a $lookup key (e.g. 'attachedTo.$lookup'), a lookup definition must be supplied to resolve which class/object the lookup points at; if `lookup` is undefined the function cannot resolve the target class and throws.

Source

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

      _class,
      label: label as IntlString,
      presenter: typeof presenter === 'string' ? await getResource(presenter) : presenter,
      props: preserveKey.props,
      displayProps: preserveKey.displayProps,
      collectionAttr: isCollectionAttr,
      isLookup: false
    }
  }
  if (key.key.length === 0) {
    const p = await getObjectPresenter(client, _class, preserveKey, isCollectionAttr)
    if (p === undefined) {
      throw new Error(`object presenter not found for class=${_class}, preserve key ${JSON.stringify(preserveKey)}`)
    }
    return p
  } else {
    if (key.key.startsWith('$lookup')) {
      if (lookup === undefined) {
        throw new Error(`lookup class does not provided for ${key.key}`)
      }
      return await getLookupPresenter(client, _class, key, preserveKey, lookup)
    }
    return await getAttributePresenter(client, _class, key.key, preserveKey, undefined, _category)
  }
}

function getKeyLookup<T extends Doc> (
  hierarchy: Hierarchy,
  _class: Ref<Class<T>>,
  key: string,
  lookup: Lookup<T>,
  lastIndex: number = 1
): Lookup<T> {
  if (!key.startsWith('$lookup')) return lookup
  const parts = key.split('.')
  const attrib = parts[1]
  const attribute = hierarchy.getAttribute(_class, attrib)

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Provide the Lookup definition for the class when calling model()/getPresenter so $lookup keys resolve
  2. Check the attribute has a $lookup entry in the class hierarchy/lookup data
  3. Fall back to getAttributePresenter (non-lookup) if no lookup is intended for that key

Example fix

// before
await model(client, _class, [{ key: 'attachedTo.$lookup' }])
// after
const lookup = await client.getLookup(_class)
await model(client, _class, [{ key: 'attachedTo.$lookup' }], undefined, undefined, lookup)
Defensive patterns

Strategy: validation

Validate before calling

function hasLookup(lookup) { return lookup !== undefined && lookup !== null }
if (!hasLookup(lookup)) throw new Error('lookup required for $lookup keys')
await model(client, _class, keys, undefined, undefined, lookup)

Type guard

function lookupKeysPresent(keys: { key: string }[]): boolean {
  return keys.every(k => !k.key.includes('$lookup'))
}

Try / catch

try {
  return await model(client, _class, keys, undefined, undefined, lookup)
} catch (err) {
  if (String(err.message).startsWith('lookup class does not provided')) {
    return await model(client, _class, keys.map(k => ({ ...k, key: k.key.replace('.$lookup', '') })))
  }
  throw err
}

Prevention

When it happens

Trigger: Calling getPresenter (via model()) with a BuildModelKey whose key contains '$lookup' while the corresponding Lookup<T> entry is undefined — e.g. building a view model for a lookup attribute without passing the class lookup data.

Common situations: Caller omitted the `lookup` argument when building models for attributes that reference other documents; view config includes $lookup keys but the client-side lookup map was not loaded; attribute is not defined in the class's lookup section.

Related errors


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