hcengineering/platform · error

Create step must have space

Error message

Create step must have space

What it means

For regular document classes, create() destructures space out of the step data and requires it to create the doc via client.createDoc, since every Huly document must live in a space. If space is undefined after destructuring, the step data lacks a space and the method throws before attempting the document creation.

Source

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

        space === undefined ||
        attachedToClass === undefined ||
        collection === undefined
      ) {
        throw new Error('Add collection step must have attachedTo, attachedToClass, collection and space')
      }
      return (await this.client.addCollection(
        _class,
        space,
        attachedTo,
        attachedToClass,
        collection,
        props,
        _id as Ref<AttachedDoc> | undefined
      )) as unknown as Ref<T>
    } else {
      const { space, ...props } = data
      if (space === undefined) {
        throw new Error('Create step must have space')
      }
      return await this.client.createDoc<T>(_class, space, props as Data<T>, _id)
    }
  }

  private async fillPropsWithMarkdown<T extends Doc, P extends Partial<T> | Props<T>>(
    data: P,
    vars: Record<string, any>,
    markdownFields?: string[]
  ): Promise<P> {
    data = await this.fillProps(data, vars)
    if (markdownFields !== undefined) {
      for (const field of markdownFields) {
        if ((data as any)[field] !== undefined) {
          try {
            const res = this.parseMarkdown((data as any)[field])
            ;(data as any)[field] = res
          } catch (error) {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Include a valid space value in the step data
  2. Verify the space reference resolves (not undefined) before running the migration
  3. If the doc should be attached instead, use the add-collection/attached branch which takes attachedTo instead

Example fix

// before
await initializer.create('contact:class:Contact', { name: 'John' } as any)
// after
await initializer.create('contact:class:Contact', { space: defaultSpace, name: 'John' })
Defensive patterns

Strategy: validation

Validate before calling

if (data == null || (data as any).space === undefined) {
  throw new Error(`Create step for ${_class} is missing space`)
}
await initializer.create(_class, data)

Type guard

function hasSpace<T extends { space?: Ref<Space> }>(d: T): d is T & { space: Ref<Space> } {
  return d.space !== undefined
}

Try / catch

try {
  await initializer.create(_class, data)
} catch (err) {
  if (err instanceof Error && err.message === 'Create step must have space') {
    console.error(`Step for ${_class} lacks space:`, data)
  }
  throw err
}

Prevention

When it happens

Trigger: Calling create() (via processCreate) for a non-attached doc class with data that has no space property, or where space is explicitly undefined (e.g. set from an unresolved variable).

Common situations: Import/migration data exported from a model version where docs were attached and didn't need space; dynamic step generation where the space value failed to resolve; forgetting to include space when hand-writing seed fixtures.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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