hcengineering/platform · error
Unsupported card type
Error message
Unsupported card type: ${cardType} in ${cardPath} What it means
Thrown by CardsProcessor.processSystemTypeCards while scanning a directory of markdown card files. Each .md file's YAML header must declare a `class:` whose value starts with the `card:types:` prefix; anything else (missing prefix, plain string, wrong namespace) is rejected. This guards the importer against malformed or foreign card headers that would otherwise be processed as system type cards.
Solutions
- Open the .md file named in the error and change its YAML header `class:` value so it starts with `card:types:` (e.g. `card:types:Company`).
- If the file is not a card, remove it from the imported directory or move it outside the scan path.
- Check for version drift: if cards came from an older export, re-export with the current importer or migrate class prefixes.
Example fix
// before (header of broken .md) class: contact:types:Person // after class: card:types:Person
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'fs'
function validateCardHeaders(dir: string): string[] {
const bad: string[] = []
for (const f of fs.readdirSync(dir, { recursive: true })) {
if (String(f).endsWith('.md')) {
const header = readYamlHeader(String(f)) // your parser
if (header.class !== undefined && !String(header.class).startsWith('card:types:')) {
bad.push(String(f))
}
}
}
return bad
} Type guard
function isCardTypeHeader(cls: unknown): cls is `card:types:${string}` {
return typeof cls === 'string' && cls.startsWith('card:types:')
} Try / catch
try {
await processor.processDirectory(dir)
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported card type:')) {
const [, cardType, cardPath] = e.message.match(/Unsupported card type: (.+?) in (.+)$/) ?? []
console.error(`Fix YAML class header in ${cardPath}: got '${cardType}', expected prefix 'card:types:'`)
} else throw e
} Prevention
- Keep card templates with the correct `class: card:types:...` header checked into the repo.
- Lint .md headers in CI before running the importer.
- Never copy YAML headers from other Huly modules without verifying the prefix.
When it happens
Trigger: Calling processDirectory (which invokes processSystemTypeCards) on a directory containing a .md file whose YAML frontmatter has `class:` set to a value that does not start with `card:types:` (e.g. `contact:types:Person`, a typo like `card:type:Company`, or a class copied from another module).
Common situations: Hand-authored cards with typos in the class prefix; cards exported from a different Huly module or older version using a different namespace; template files copied from other tooling where the header class was never updated.
Related errors
- Invalid import schema in
- Invalid master tag data
- Invalid tag data
- Invalid at : \n `).join('\n')}
- Invalid workspace: \n
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/b8e804673f6d4d38.
Report an issue: GitHub.
Appendix: source
Thrown at packages/importer/src/huly/cards.ts:238
}
}
}
private async processSystemTypeCards (
currentDir: string,
result: UnifiedDocProcessResult,
masterTagAssociaions: Map<string, AssociationMetadata>,
masterTagAttributes: Map<string, UnifiedDoc<Attribute<MasterTag>>>
): Promise<void> {
const entries = fs.readdirSync(currentDir, { withFileTypes: true })
for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.md')) {
const cardPath = path.join(currentDir, entry.name)
const { class: cardType, ...cardProps } = this.parser.readYamlHeader(cardPath)
if (cardType !== undefined && cardType.startsWith('card:types:') === false) {
throw new Error('Unsupported card type: ' + cardType + ' in ' + cardPath)
}
await this.processCard(result, cardPath, cardProps, cardType, masterTagAssociaions, masterTagAttributes)
} else if (entry.isDirectory() && (entry.name === card.types.File || entry.name === card.types.Document)) {
await this.processCards(path.join(currentDir, entry.name), result, masterTagAssociaions, masterTagAttributes)
}
}
}
private async processCard (
result: UnifiedDocProcessResult,
cardPath: string,
cardProps: Record<string, any>,
masterTagId: Ref<MasterTag>,
masterTagAssociaions: Map<string, AssociationMetadata>,
masterTagAttributes: Map<string, UnifiedDoc<Attribute<MasterTag>>>,
parentCardId?: Ref<Card>
): Promise<void> {View on GitHub (pinned to 63e28dc964)