{"record":{"id":"1b5a75ad517c6945","repo":"hcengineering/platform","slug":"createdoc-cannot-be-used-for-objects-inherited-fro","errorCode":null,"errorMessage":"createDoc cannot be used for objects inherited from AttachedDoc","messagePattern":"createDoc cannot be used for objects inherited from AttachedDoc","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"foundations/core/packages/core/src/operations.ts","lineNumber":111,"sourceCode":"  searchFulltext (query: SearchQuery, options: SearchOptions): Promise<SearchResult> {\n    return this.client.searchFulltext(query, options)\n  }\n\n  tx (tx: Tx): Promise<TxResult> {\n    return this.client.tx(tx)\n  }\n\n  async createDoc<T extends Doc>(\n    _class: Ref<Class<T>>,\n    space: Ref<Space>,\n    attributes: Data<T>,\n    id?: Ref<T>,\n    modifiedOn?: Timestamp,\n    modifiedBy?: PersonId\n  ): Promise<Ref<T>> {\n    const hierarchy = this.client.getHierarchy()\n    if (hierarchy.isDerived(_class, core.class.AttachedDoc)) {\n      throw new Error('createDoc cannot be used for objects inherited from AttachedDoc')\n    }\n    if (hierarchy.findDomain(_class) === DOMAIN_MODEL && space !== core.space.Model) {\n      throw new Error('createDoc cannot be called for DOMAIN_MODEL classes with non-model space')\n    }\n    const tx = this.txFactory.createTxCreateDoc(_class, space, attributes, id, modifiedOn, modifiedBy)\n    await this.tx(tx)\n    return tx.objectId\n  }\n\n  async addCollection<T extends Doc, P extends AttachedDoc>(\n    _class: Ref<Class<P>>,\n    space: Ref<Space>,\n    attachedTo: Ref<T>,\n    attachedToClass: Ref<Class<T>>,\n    collection: Extract<keyof T, string> | string,\n    attributes: AttachedData<P>,\n    id?: Ref<P>,\n    modifiedOn?: Timestamp,","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/core/src/operations.ts#L93-L129","documentation":"OperationalOperations.createDoc creates top-level documents via a TxCreateDoc. AttachedDoc instances (attachments, comments, etc.) must be created with createAttachedDoc so their attachedTo/attachedToClass are wired and collection counters updated; calling createDoc for such classes is rejected with this plain Error.","triggerScenarios":"Calling createDoc with a _class parameter that derives from core.class.AttachedDoc (checked via hierarchy.isDerived), e.g. trying to create a Comment, Attachment, or custom attached object as if it were a space-level document.","commonSituations":"Copying creation code between a parent doc and its attachment; refactoring a Doc subclass into an AttachedDoc subclass without updating creation sites; generic factory functions that pass arbitrary class refs.","solutions":["Use createAttachedDoc(...) for classes derived from AttachedDoc, providing attachedTo/attachedToClass/collection","Branch on hierarchy.isDerived(_class, core.class.AttachedDoc) to choose the right creation API","If the class should be top-level, change it so it no longer extends AttachedDoc","Update generic helpers to detect AttachedDoc subclasses and route accordingly"],"exampleFix":"// before\nawait ops.createDoc(comment.class.Comment, space, { message })\n// after\nawait ops.createAttachedDoc(\n  comment.class.Comment,\n  space,\n  { message },\n  parentDoc._id,\n  parentDoc._class,\n  'comments'\n)","handlingStrategy":"type-guard","validationCode":"const hierarchy = client.getHierarchy()\nif (hierarchy.isDerived(_class, core.class.AttachedDoc)) {\n  throw new Error(`${String(_class)} is an AttachedDoc; use createAttachedDoc`)\n}\nawait ops.createDoc(_class, space, attributes)","typeGuard":"function isAttachedClass(h: Hierarchy, c: Ref<Class<Doc>>): boolean {\n  return h.isDerived(c, core.class.AttachedDoc)\n}","tryCatchPattern":"try {\n  await ops.createDoc(_class, space, attrs)\n} catch (err) {\n  if ((err as Error).message.includes('AttachedDoc')) {\n    return ops.createAttachedDoc(_class as Ref<AttachedDoc>, space, attrs, attachedTo, attachedToClass, collection)\n  }\n  throw err\n}","preventionTips":["Check isDerived(_class, core.class.AttachedDoc) before any generic create","Route attachment-like entities through createAttachedDoc with attachedTo/collection","Update creation sites when a class is refactored into an AttachedDoc","Encode creation helpers that branch automatically on AttachedDoc derivation"],"tags":["operations","attached-doc","api-misuse"],"backgroundTag":"attached-doc-created-as-root","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}