{"record":{"id":"330a547fdfa47e97","repo":"hcengineering/platform","slug":"update-step-must-have-id-and-space","errorCode":null,"errorMessage":"Update step must have _id and space","messagePattern":"Update step must have _id and space","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/tool/src/initializer.ts","lineNumber":240,"sourceCode":"    if (step.resultVariable !== undefined) {\n      vars[`\\${${step.resultVariable}}`] = res\n    }\n  }\n\n  private async processMixin<T extends Doc>(step: MixinStep<T, T>, vars: Record<string, any>): Promise<void> {\n    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)\n    const { _id, space, ...props } = data\n    if (_id === undefined || space === undefined) {\n      throw new Error('Mixin step must have _id and space')\n    }\n    await this.client.createMixin(_id, step._class, space, step.mixin, props)\n  }\n\n  private async processUpdate<T extends Doc>(step: UpdateStep<T>, vars: Record<string, any>): Promise<void> {\n    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)\n    const { _id, space, ...props } = data\n    if (_id === undefined || space === undefined) {\n      throw new Error('Update step must have _id and space')\n    }\n    await this.client.updateDoc(step._class, space, _id as Ref<Doc>, props)\n  }\n\n  private async processBulkUpdate<T extends Doc>(step: BulkUpdateStep<T>, vars: Record<string, any>): Promise<void> {\n    const ops = this.client.apply()\n    const docs = await this.client.findAll(step._class, { ...(step.query as any) })\n    const data = await this.fillPropsWithMarkdown(step.data, vars, step.markdownFields)\n    for (const doc of docs) {\n      await ops.updateDoc(step._class, doc.space, doc._id, data)\n    }\n    await ops.commit()\n  }\n\n  private async processCreate<T extends Doc>(\n    step: CreateStep<T>,\n    vars: Record<string, any>,\n    defaults: Map<Ref<Class<T>>, Props<T>>","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/tool/src/initializer.ts#L222-L258","documentation":"An UpdateStep's filled data must carry the _id and space of the document to update, because client.updateDoc(step._class, space, _id, props) requires both. When either is undefined after variable substitution the step is malformed and fails with this error. Like the mixin variant, it indicates a defective or under-specified update step in the init/update script.","triggerScenarios":"An UpdateStep whose data lacks _id or space after fillPropsWithMarkdown — omitted fields, or ${var} placeholders that resolved to undefined because no earlier step bound them.","commonSituations":"Scripts copied from examples with placeholder _id/space never replaced; dependent variables not defined by a preceding FindStep; bulk-generated scripts where some steps lost required identity fields.","solutions":["Add the correct _id and space to the update step data.","Reference a document found by a previous FindStep via its resultVariable so _id/space are filled at runtime.","Validate the script offline (parse all UpdateSteps and assert _id/space presence) before running it against a workspace."],"exampleFix":"// before\nawait this.client.updateDoc(step._class, space as Ref<Space>, _id as Ref<Doc>, props) // throws when _id/space undefined\n// after\nif (data._id === undefined) throw new Error(`Update step ${step._id} missing _id`)\nawait this.client.updateDoc(step._class, data.space as Ref<Space>, data._id as Ref<Doc>, props)","handlingStrategy":"validation","validationCode":"for (const step of script.steps) {\n  if (stepIsUpdate(step) && (step.data._id === undefined || step.data.space === undefined)) {\n    throw new Error(`UpdateStep missing _id/space: ${JSON.stringify(step).slice(0, 120)}`)\n  }\n}","typeGuard":"function isUpdatable<T extends Doc>(d: Partial<T> | undefined): d is T & { _id: Ref<T>, space: Ref<Space> } {\n  return d !== undefined && d._id !== undefined && (d as any).space !== undefined\n}","tryCatchPattern":"try {\n  await this.client.updateDoc(step._class, space, _id as Ref<Doc>, props)\n} catch (err) {\n  if ((err as Error).message === 'Update step must have _id and space') {\n    console.error('UpdateStep data must include _id and space; check variable bindings', step)\n  }\n  throw err\n}","preventionTips":["Always include _id and space in update step data.","Source _id/space from a preceding FindStep resultVariable instead of hardcoding.","Dry-run/validate all steps before applying updates to a workspace.","After script edits, re-check that identity fields were not dropped."],"tags":["initialization","update","validation","missing-field"],"backgroundTag":"missing-required-fields","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}