{"record":{"id":"0e3f2776f2db1504","repo":"hcengineering/platform","slug":"cannot-create-card-with-base-type-type","errorCode":null,"errorMessage":"Cannot create card with base type ${type}","messagePattern":"Cannot create card with base type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/card-resources/src/utils.ts","lineNumber":586,"sourceCode":"      docCreatedBy: card.docCreatedBy ?? card.createdBy ?? card.modifiedBy\n    },\n    mixin,\n    true\n  )\n}\n\nexport async function createCard (\n  type: Ref<MasterTag>,\n  space: Ref<Space>,\n  data: Partial<Data<Card>> = {},\n  contentMarkup: Markup = EmptyMarkup,\n  id?: Ref<Card>\n): Promise<Ref<Card>> {\n  const client = getClient()\n  const hierarchy = client.getHierarchy()\n\n  if (isBaseTypeWithSubtypes(hierarchy, type)) {\n    throw new Error(`Cannot create card with base type ${type}`)\n  }\n\n  const title = data.title ?? (await translate(card.string.Card, {}))\n\n  const _id = id ?? generateId()\n  const content = isEmptyMarkup(contentMarkup)\n    ? ('' as MarkupBlobRef)\n    : await createMarkup(makeCollabId(type, _id, 'content'), contentMarkup)\n\n  const _data: Data<Card> = {\n    parentInfo: [],\n    blobs: {},\n    ...data,\n    title,\n    rank: '',\n    content\n  }\n","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/card-resources/src/utils.ts#L568-L604","documentation":"createCard rejects types for which isBaseTypeWithSubtypes(hierarchy, type) is true — abstract/base card types that only exist to be subclassed and have no direct instances. Instantiating such a type would produce an invalid card, so the function throws.","triggerScenarios":"Calling createCard (directly or via cardFactory) with a base/abstract card class — e.g. passing card.class.Card or another parent type instead of a concrete subtype like a task or issue class.","commonSituations":"Generic UI letting users pick 'Card' instead of a concrete kind; factory code defaulting to the base type when no subtype specified; plugins registering new subtypes but old configs still referencing the base class.","solutions":["Pass a concrete card subtype class (one without registered subtypes) instead of the base type","Check with isBaseTypeWithSubtypes in UI code and hide base types from creation pickers","Update cardFactory configurations/default types to concrete classes"],"exampleFix":"// before\nawait createCard(type, space, data) // type is base card class\n// after\nif (isBaseTypeWithSubtypes(hierarchy, type)) {\n  type = concreteSubtypeFor(type) // pick a registered subtype\n}\nawait createCard(type, space, data)","handlingStrategy":"validation","validationCode":"const hierarchy = client.getHierarchy()\nif (isBaseTypeWithSubtypes(hierarchy, type)) {\n  type = pickConcreteSubtype(type) // must resolve to a non-base class\n}","typeGuard":"const isConcreteCardType = (h: Hierarchy, type: Ref<Class<Card>>): boolean =>\n  !isBaseTypeWithSubtypes(h, type)","tryCatchPattern":"try {\n  await createCard(type, space, data)\n} catch (err) {\n  if ((err as Error).message.startsWith('Cannot create card with base type')) {\n    // prompt user to pick a concrete card kind\n  } else throw err\n}","preventionTips":["Filter base classes out of card-creation type pickers using isBaseTypeWithSubtypes","Always specify a concrete subtype in cardFactory configs","Add a unit test asserting createCard rejects base types and accepts subtypes"],"tags":["card","validation","hierarchy"],"backgroundTag":"abstract-type-instantiation","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}