hcengineering/platform · error
Cannot create card with base type ${type}
Error message
Cannot create card with base type ${type} What it means
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.
Source
Thrown at plugins/card-resources/src/utils.ts:586
docCreatedBy: card.docCreatedBy ?? card.createdBy ?? card.modifiedBy
},
mixin,
true
)
}
export async function createCard (
type: Ref<MasterTag>,
space: Ref<Space>,
data: Partial<Data<Card>> = {},
contentMarkup: Markup = EmptyMarkup,
id?: Ref<Card>
): Promise<Ref<Card>> {
const client = getClient()
const hierarchy = client.getHierarchy()
if (isBaseTypeWithSubtypes(hierarchy, type)) {
throw new Error(`Cannot create card with base type ${type}`)
}
const title = data.title ?? (await translate(card.string.Card, {}))
const _id = id ?? generateId()
const content = isEmptyMarkup(contentMarkup)
? ('' as MarkupBlobRef)
: await createMarkup(makeCollabId(type, _id, 'content'), contentMarkup)
const _data: Data<Card> = {
parentInfo: [],
blobs: {},
...data,
title,
rank: '',
content
}
View on GitHub (pinned to 63e28dc964)
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
Example fix
// before
await createCard(type, space, data) // type is base card class
// after
if (isBaseTypeWithSubtypes(hierarchy, type)) {
type = concreteSubtypeFor(type) // pick a registered subtype
}
await createCard(type, space, data) Defensive patterns
Strategy: validation
Validate before calling
const hierarchy = client.getHierarchy()
if (isBaseTypeWithSubtypes(hierarchy, type)) {
type = pickConcreteSubtype(type) // must resolve to a non-base class
} Type guard
const isConcreteCardType = (h: Hierarchy, type: Ref<Class<Card>>): boolean => !isBaseTypeWithSubtypes(h, type)
Try / catch
try {
await createCard(type, space, data)
} catch (err) {
if ((err as Error).message.startsWith('Cannot create card with base type')) {
// prompt user to pick a concrete card kind
} else throw err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- Message id is required
- Message id is required
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/0e3f2776f2db1504.
Report an issue: GitHub.