hcengineering/platform · error

Unknown step: ${step.name}

Error message

Unknown step: ${step.name}

What it means

The docx importer's constructor resolves each entry of `options.steps` against a registry of known preprocessor step specs (`specs[step.name]`). If a step name is not in the registry, construction fails immediately with 'Unknown step: <name>'. This is a configuration validation error — no processing starts.

Source

Thrown at packages/importer/src/docx/docx.ts:60

export type DocumentPreprocessor = (document: DocumentState) => DocumentState | undefined
export type DocumentPreprocessorSpec<T> = (converter: DocumentConverter, options?: T) => DocumentPreprocessor

export class DocumentConverter {
  documents = new Map<string, DocumentState>()
  output = new Map<string, Buffer | string>()
  preprocessors: DocumentPreprocessor[]

  options: DocumentConverterOptions

  constructor (options: DocumentConverterOptions, specs: Record<string, DocumentPreprocessorSpec<any>>) {
    this.options = options
    this.preprocessors = []

    for (const step of options.steps) {
      const spec = specs[step.name]
      if (spec === undefined) {
        throw new Error(`Unknown step: ${step.name}`)
      }
      this.preprocessors.push(spec(this, step.options))
    }
  }

  async processFolder (root: string): Promise<void> {
    const files = await scanFiles(root)
    for (const path of files) {
      const ext = extname(path)
      if (ext === '.docx') await this.processDocument(path, root)
      else if (ext === '.md') this.addOutputFile(relative(root, path), await readFile(path, 'utf-8'))
    }
  }

  async processDocument (path: string, root: string): Promise<void> {
    const htmlString = await this.options.htmlConverter(path)
    const markup = htmlToJSON(htmlString)

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the step name against the supported step names in the specs registry in packages/importer/src/docx/docx.ts
  2. Fix the typo/rename in the options.steps configuration
  3. If a custom step is needed, register its spec in the specs map before constructing the processor
  4. Pin the importer version matching your configuration, or migrate step names after upgrading

Example fix

// before
new DocxProcessor({ steps: [{ name: 'remove-header', options: {} }] })
// after
new DocxProcessor({ steps: [{ name: 'header', options: { action: 'remove' } }] }) // a name present in specs
Defensive patterns

Strategy: validation

Validate before calling

import { specs } from './specs' // or expose the registry
const valid = new Set(Object.keys(specs))
for (const step of options.steps) {
  if (!valid.has(step.name)) throw new Error(`Unknown step '${step.name}'. Valid: ${[...valid].join(', ')}`)
}

Type guard

function isKnownStep(name: string, valid: readonly string[]): name is typeof valid[number] {
  return (valid as readonly string[]).includes(name)
}

Try / catch

try {
  const processor = new DocxProcessor(options)
} catch (err) {
  if (/^Unknown step: /.test((err as Error).message)) {
    console.error((err as Error).message, '— check supported step names')
  }
  throw err
}

Prevention

When it happens

Trigger: Constructing the docx processor with `options.steps` containing a `step.name` not present in the built-in `specs` map: typo, renamed step, or a custom step never registered.

Common situations: Copy-pasting step configs between importer versions where step names changed; inventing step names expecting pluggability without registering a spec; misspelling a valid step name (case-sensitivity included).

Related errors


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