hcengineering/platform · error · Error

createDoc cannot be called for DOMAIN_MODEL classes with non

Error message

createDoc cannot be called for DOMAIN_MODEL classes with non-model space

What it means

createDoc also enforces that classes living in the model domain (DOMAIN_MODEL, i.e. classifier/definition objects) may only be created in core.space.Model. Creating a model-domain class into a user workspace space would corrupt the model, so the operation throws this Error before generating the tx.

Source

Thrown at foundations/core/packages/core/src/operations.ts:114

  tx (tx: Tx): Promise<TxResult> {
    return this.client.tx(tx)
  }

  async createDoc<T extends Doc>(
    _class: Ref<Class<T>>,
    space: Ref<Space>,
    attributes: Data<T>,
    id?: Ref<T>,
    modifiedOn?: Timestamp,
    modifiedBy?: PersonId
  ): Promise<Ref<T>> {
    const hierarchy = this.client.getHierarchy()
    if (hierarchy.isDerived(_class, core.class.AttachedDoc)) {
      throw new Error('createDoc cannot be used for objects inherited from AttachedDoc')
    }
    if (hierarchy.findDomain(_class) === DOMAIN_MODEL && space !== core.space.Model) {
      throw new Error('createDoc cannot be called for DOMAIN_MODEL classes with non-model space')
    }
    const tx = this.txFactory.createTxCreateDoc(_class, space, attributes, id, modifiedOn, modifiedBy)
    await this.tx(tx)
    return tx.objectId
  }

  async addCollection<T extends Doc, P extends AttachedDoc>(
    _class: Ref<Class<P>>,
    space: Ref<Space>,
    attachedTo: Ref<T>,
    attachedToClass: Ref<Class<T>>,
    collection: Extract<keyof T, string> | string,
    attributes: AttachedData<P>,
    id?: Ref<P>,
    modifiedOn?: Timestamp,
    modifiedBy?: PersonId
  ): Promise<Ref<P>> {
    const tx = this.txFactory.createTxCollectionCUD<T, P>(

View on GitHub (pinned to 63e28dc964)

Solutions

  1. If the object is a definition/classifier, create it via a model tx (upgrade/derive) rather than createDoc, or use space core.space.Model
  2. If it is real user data, move the class out of the model domain (do not derive from Classifier/Doc-with-model-domain definitions)
  3. Route model-domain creation through plugin model packages installed during upgrades
  4. Add a pre-check hierarchy.findDomain(_class) === DOMAIN_MODEL ? core.space.Model : space in generic helpers

Example fix

// before
await ops.createDoc(core.class.State, projectSpace, stateAttrs)
// after
await ops.createDoc(core.class.State, core.space.Model, stateAttrs) // model-domain classes require model space
Defensive patterns

Strategy: validation

Validate before calling

const hierarchy = client.getHierarchy()
const domain = hierarchy.findDomain(_class)
if (domain === 'model' && space !== core.space.Model) {
  throw new Error(`${String(_class)} is a model-domain class; must use core.space.Model`)
}
await ops.createDoc(_class, space, attributes)

Try / catch

try {
  await ops.createDoc(_class, space, attrs)
} catch (err) {
  if ((err as Error).message.includes('DOMAIN_MODEL')) {
    return ops.createDoc(_class, core.space.Model, attrs) // or reject - model classes should not be user-created
  }
  throw err
}

Prevention

When it happens

Trigger: Calling createDoc with a class whose hierarchy.findDomain(_class) === 'model' while passing a non-model space (any user space), e.g. trying to instantiate a Class, Interface, Mixin, or plugin-defined classifier into a project space.

Common situations: Generic creation UIs that let users pick any registered class; scripts creating 'type' objects in workspaces instead of registering them via model tx/upgrade; confusion between model classes and data classes.

Related errors


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