hcengineering/platform · warning · ProcessError

process.error.EmptyAttributeContextValue

process.error.EmptyAttributeContextValue

Error message

Empty attribute value: {attr}

What it means

Thrown by getAttributeValue when the attribute value resolved from the card for a context key is null or undefined. The error message includes the human-readable attribute label (or embedded label) so the user knows which attribute was empty.

Source

Thrown at server-plugins/process-resources/src/utils.ts:97

  const hierarchy = control.client.getHierarchy()
  const _process = control.client.getModel().findObject(execution.process)
  if (_process === undefined) throw processError(process.error.ObjectNotFound, { _id: execution.process })
  const realKey = resolveAttributeId(_process, rawKey)
  const key = checkMixinKey(realKey, _process.masterTag, hierarchy)
  return getObjectValue(key, card)
}

function getConstValue (control: ProcessControl, execution: Execution, context: SelectedConst): any {
  return context.value
}

function getAttributeValue (control: ProcessControl, execution: Execution, context: SelectedContext): any {
  const card = control.cache.get(execution.card)
  if (card !== undefined) {
    const val = getValue(control, execution, context.key, card)
    if (val == null) {
      const attr = control.client.getHierarchy().findAttribute(card._class, context.key)
      throw processError(
        process.error.EmptyAttributeContextValue,
        {},
        { attr: attr?.label ?? getEmbeddedLabel(context.key) }
      )
    }
    return val
  } else {
    throw processError(process.error.ObjectNotFound, { _id: execution.card }, {}, true)
  }
}

async function fillValue (
  value: any,
  context: SelectedContext,
  control: ProcessControl,
  execution: Execution
): Promise<any> {
  for (const func of context.functions ?? []) {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the card and ensure the attribute (by context.key) has a value before triggering the context value resolution.
  2. Set a default/initial value for the attribute in the process template or on card creation.
  3. Verify context.key resolves to the intended attribute (check resolveAttributeId / mixin key mapping) in case the key is wrong.
  4. Add a client-side null/undefined check and handle the empty case (prompt user, skip action) instead of calling into the plugin.

Example fix

// before
const value = await getContextValue(ctx, control, execution)
// after: guard empty value before use
const card = control.cache.get(execution.card)
const value = card != null ? getValue(control, execution, 'Status', card) : undefined
if (value == null) value = await promptUserFor('Status')
Defensive patterns

Strategy: validation

Validate before calling

const card = control.cache.get(execution.card)
const attr = control.client.getHierarchy().findAttribute(card?._class, context.key)
const value = card != null ? (card as any)[context.key] : undefined
if (value == null) throw new Error(`Attribute ${attr?.label ?? context.key} is empty`)

Type guard

function hasValue<T extends Doc>(card: T | undefined, key: string): card is T & Record<string, unknown> {
  return card !== undefined && (card as any)[key] != null
}

Try / catch

try {
  const value = await getContextValue(ctx, control, execution)
} catch (err) {
  if ((err as Error).message.startsWith('Empty attribute value')) {
    // prompt user or substitute default
  } else throw err
}

Prevention

When it happens

Trigger: getContextValue resolves a SelectedContext whose card is cached but whose attribute (context.key, resolved against the process) is null/undefined on the card — e.g. an unfilled required field, a not-yet-computed value, or a wrong key pointing at an empty attribute.

Common situations: Process templates referencing attributes that users haven't filled in; attributes whose values are only set later in the process; typos or renamed attributes yielding empty lookups; optional reference fields left blank.

Related errors


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