hcengineering/platform · error

Mixin step must have _id and space

Error message

Mixin step must have _id and space

What it means

A MixinStep's filled data must identify the target document by its _id and space, since createMixin needs both to locate and update the document. If either is missing after variable substitution, the step is malformed and the initializer throws this error. This is a script-authoring error, not a runtime infrastructure failure.

Source

Thrown at server/tool/src/initializer.ts:231

    }
  }

  private async processFind<T extends Doc>(step: FindStep<T>, vars: Record<string, any>): Promise<void> {
    const query = this.fillProps(step.query, vars)
    const res = await this.client.findOne(step._class, { ...(query as any) })
    if (res === undefined) {
      throw new Error(`Document not found: ${JSON.stringify(query)}`)
    }
    if (step.resultVariable !== undefined) {
      vars[`\${${step.resultVariable}}`] = res
    }
  }

  private async processMixin<T extends Doc>(step: MixinStep<T, T>, vars: Record<string, any>): Promise<void> {
    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)
    const { _id, space, ...props } = data
    if (_id === undefined || space === undefined) {
      throw new Error('Mixin step must have _id and space')
    }
    await this.client.createMixin(_id, step._class, space, step.mixin, props)
  }

  private async processUpdate<T extends Doc>(step: UpdateStep<T>, vars: Record<string, any>): Promise<void> {
    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)
    const { _id, space, ...props } = data
    if (_id === undefined || space === undefined) {
      throw new Error('Update step must have _id and space')
    }
    await this.client.updateDoc(step._class, space, _id as Ref<Doc>, props)
  }

  private async processBulkUpdate<T extends Doc>(step: BulkUpdateStep<T>, vars: Record<string, any>): Promise<void> {
    const ops = this.client.apply()
    const docs = await this.client.findAll(step._class, { ...(step.query as any) })
    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)
    for (const doc of docs) {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Add the target document's _id and space to the step data.
  2. Bind the missing value via an earlier FindStep setting a resultVariable, and reference it (${...}) in the mixin data.
  3. Log/print the filled data before the call to see which field resolved to undefined.

Example fix

// before
{ "_class": "contact:class:Person", "mixin": "...", "data": { "rank": 5 } }
// after
{ "_class": "contact:class:Person", "mixin": "...", "data": { "_id": "contact:person:Id", "space": "core:space:Space", "rank": 5 } }
Defensive patterns

Strategy: validation

Validate before calling

for (const step of script.steps) {
  if (stepIsMixin(step) && (step.data._id === undefined || step.data.space === undefined)) {
    throw new Error(`MixinStep missing _id/space: ${JSON.stringify(step).slice(0, 120)}`)
  }
}

Type guard

function hasIdAndSpace<T extends Doc>(d: Partial<T> | undefined): d is T & { _id: Ref<T>, space: Ref<Space> } {
  return d !== undefined && d._id !== undefined && (d as any).space !== undefined
}

Try / catch

try {
  await this.client.createMixin(_id, step._class, space, step.mixin, props)
} catch (err) {
  if ((err as Error).message === 'Mixin step must have _id and space') {
    console.error('MixinStep data must include _id and space; check variable bindings', step)
  }
  throw err
}

Prevention

When it happens

Trigger: A MixinStep whose data object (after fillPropsWithMarkdown substitution) lacks _id or space — e.g. the step data references variables that resolved to undefined, or the author simply omitted them.

Common situations: Hand-written init/update scripts forgetting _id/space in mixin steps; a ${var} placeholder not bound by an earlier Find step, resolving to undefined; refactoring of script JSON that dropped required fields.

Related errors


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