hcengineering/platform · error
invalid relation key ${key.key}
Error message
invalid relation key ${key.key} What it means
getRelationPresenter resolves association-based relation keys (containing $associations). The key must contain a dot-separated path; if the key has no '.' it cannot encode an association and the function throws immediately.
Source
Thrown at plugins/view-resources/src/utils.ts:639
key: '',
sortingKey: '',
presenter: ErrorPresenter,
label: stringKey as IntlString,
_class: core.class.TypeString,
props: { error: err },
collectionAttr: false,
isLookup: false
}
return errorPresenter
}
})
return (await Promise.all(model)).filter((a) => a !== undefined)
}
async function getRelationPresenter (client: Client, key: BuildModelKey): Promise<AttributeModel> {
const parts = key.key.split('.')
if (parts.length < 2) {
throw new Error('invalid relation key ' + key.key)
}
// Find the last association segment
let lastAssocIndex = -1
for (let i = 0; i < parts.length; i++) {
if (parts[i] === '$associations' && i + 1 < parts.length) {
lastAssocIndex = i
}
}
if (lastAssocIndex === -1) {
throw new Error('invalid relation key ' + key.key)
}
const fragments = parts[lastAssocIndex + 1].split('_')
const assocId = fragments[0] as Ref<Association>
const assoc = client.getModel().findObject(assocId)
if (assoc === undefined) {
throw new Error('association not found for ' + assocId)View on GitHub (pinned to 63e28dc964)
Solutions
- Use a full relation key of the form 'path.$associations.assocId_x', e.g. 'spaces.$associations.space_a'
- Verify the key string contains at least one '.' before passing to model()
- Split logic: only route keys containing '$associations' to relation presenter
Example fix
// before
{ key: '$associations' }
// after
{ key: 'spaces.$associations.<assocId>_a' } Defensive patterns
Strategy: validation
Validate before calling
function isValidRelationKey(key: string): boolean {
return key.includes('.') && key.includes('$associations')
}
if (!isValidRelationKey(key)) throw new Error('bad relation key: ' + key) Try / catch
try {
return await model(client, _class, [{ key }])
} catch (err) {
if (String(err.message).startsWith('invalid relation key')) {
console.warn('malformed relation key, skipping:', key)
return []
}
throw err
} Prevention
- Build relation keys programmatically (`${path}.$associations.${assocId}_${side}`) instead of hand-writing strings
- Validate view config keys at load time
- Reuse existing key constants from the view module
When it happens
Trigger: Passing a BuildModelKey to model()/getPresenter whose key contains '$associations' but has no dot, e.g. key: '$associations' or key: 'myKey' routed to relation presenter.
Common situations: Hand-written view key strings missing the dotted path; copy-pasted keys from another view with different structure; typos that drop the association id segment.
Related errors
- lookup class does not provided for ${key}
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- Message id is required
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/34fb26e572b6deda.
Report an issue: GitHub.