hcengineering/platform · error

Unknown issue class ${issueHeader.class} in ${issueFile}

Error message

Unknown issue class ${issueHeader.class} in ${issueFile}

What it means

While walking an imported project folder, processIssuesRecursively reads each .md file's YAML front-matter and dispatches on `class`. Files with no class are skipped, but a file that declares a class other than tracker.class.Issue cannot be imported as an issue, so the importer throws. This indicates a malformed or non-issue markdown file inside a project directory.

Source

Thrown at packages/importer/src/huly/huly.ts:511

          assignee: this.findPersonByName(issueHeader.assignee),
          // Gantt scheduling fields
          startDate: parseIsoDate(issueHeader.startDate),
          dueDate: parseIsoDate(issueHeader.dueDate),
          deadline: parseIsoDate(issueHeader.deadline),
          componentLabel: issueHeader.component,
          milestoneLabel: issueHeader.milestone,
          predecessors: issueHeader.predecessors
        }

        builder.addIssue(projectPath, issuePath, issue, parentIssuePath)

        // Process sub-issues if they exist
        const subDir = path.join(currentPath, issueFile.replace('.md', ''))
        if (fs.existsSync(subDir) && fs.statSync(subDir).isDirectory()) {
          await this.processIssuesRecursively(builder, projectIdentifier, projectPath, subDir, issuePath)
        }
      } else {
        throw new Error(`Unknown issue class ${issueHeader.class} in ${issueFile}`)
      }
    }
  }

  private findPersonByName (name?: string): Ref<Person> | undefined {
    if (name === undefined) {
      return undefined
    }

    const person = this.personsByName.get(name)
    if (person === undefined) {
      throw new Error(`Person not found: ${name}`)
    }
    return person
  }

  private async getPersonIdByEmail (email: string): Promise<PersonId> {
    const personId = this.personIdByEmail.get(email)

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the `class:` field in the front-matter of the reported issueFile
  2. Set it to tracker.class.Issue (the exact identifier used by the matching Huly version)
  3. Move non-issue markdown files (documents, notes) out of the project's issue directory
  4. Re-export from the source Huly workspace to regenerate correctly-classed issue files

Example fix

// before (123..md front-matter)
class: tracker.class.Task
// after
class: tracker.class.Issue
Defensive patterns

Strategy: validation

Validate before calling

const files = fs.readdirSync(projectDir).filter(f => f.endsWith('.md'))
for (const f of files) {
  const header = readYamlHeader(path.join(projectDir, f))
  if (header?.class !== undefined && header.class !== 'tracker.class.Issue') {
    throw new Error(`${f}: expected tracker.class.Issue, got ${header.class}`)
  }
}

Type guard

function isIssueHeader(h: unknown): h is HulyIssueHeader & { class: 'tracker.class.Issue' } {
  return typeof h === 'object' && h !== null && (h as any).class === 'tracker.class.Issue'
}

Try / catch

try {
  await importer.workspaceData(folder)
} catch (e) {
  if (e instanceof Error && e.message.includes('Unknown issue class')) {
    console.error('Non-issue markdown inside project folder:', e.message)
  } else throw e
}

Prevention

When it happens

Trigger: processImportFolder → processIssuesRecursively encounters an issue .md file whose front-matter `class:` is set to something other than tracker.class.Issue (or a stale/foreign class id from a different export version).

Common situations: Hand-crafted issue files with a typo in the class; copying markdown files from another Huly area (e.g. documents) into a project folder; a version mismatch where the tracker Issue class identifier changed between export and import.

Related errors


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