hcengineering/platform · error

Author or owner not found

Error message

Author or owner not found: ${header.author} or ${header.owner}

What it means

When constructing a controlled document, the importer resolves both `header.author` and `header.owner` to Employee references via findEmployeeByName, which throws on unknown names. This guard compares against undefined to produce a clearer combined message, but since findEmployeeByName never returns undefined for unknown names, the resolution error surfaces before this check in practice — meaning the underlying cause is always an unresolvable author or owner name.

Solutions

  1. Ensure both author and owner exist as Employees in the target workspace with exactly matching names
  2. Correct the author/owner front-matter fields in the document markdown to existing employee names
  3. Reassign to a valid employee (e.g. the document maintainer) and re-run the import
  4. Re-export after the target workspace employee records are aligned

Example fix

// before (doc front-matter)
author: J. Doe
owner: ghost-user
// after
author: Jane Doe
owner: Jane Doe
Defensive patterns

Strategy: validation

Validate before calling

for (const doc of controlledDocs) {
  for (const field of ['author', 'owner'] as const) {
    const name = doc.frontMatter[field]
    if (typeof name === 'string' && !employeeNames.has(name)) {
      throw new Error(`${doc.path}: ${field} "${name}" is not an employee in the target workspace`)
    }
  }
}

Type guard

function hasResolvableAuthorOwner(h: { author: string; owner: string }, employees: Set<string>): boolean {
  return employees.has(h.author) && employees.has(h.owner)
}

Try / catch

try {
  await importer.workspaceData(folder)
} catch (e) {
  if (e instanceof Error && (e.message.startsWith('Author or owner not found') || e.message.startsWith('Employee not found'))) {
    console.error('Set author/owner to existing employees in the document front-matter:', e.message)
  } else throw e
}

Prevention

When it happens

Trigger: Importing a controlled document whose front-matter `author:` or `owner:` names are not present in employeesByName (HulyFormatImporter → processControlledDocument path); typical when the named employees do not exist in the target workspace or their names differ.

Common situations: Authors who left the organization; documents authored by contractors never onboarded to the target workspace; name casing/spelling differences between the export and the target workspace's employee records.

Related errors


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

Appendix: source

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

      qualified: data.qualified !== undefined ? this.findAccountByName(data.qualified) : undefined,
      manager: data.manager !== undefined ? this.findAccountByName(data.manager) : undefined,
      qara: data.qara !== undefined ? this.findAccountByName(data.qara) : undefined,
      docs: []
    }
  }

  private async processControlledDocument (
    header: HulyControlledDocumentHeader,
    docPath: string,
    id: Ref<ControlledDocument>,
    metaId: Ref<DocumentMeta>
  ): Promise<ImportControlledDocument> {
    const codeMatch = path.basename(docPath).match(/^\[([^\]]+)\]/)

    const author = this.findEmployeeByName(header.author)
    const owner = this.findEmployeeByName(header.owner)
    if (author === undefined || owner === undefined) {
      throw new Error(`Author or owner not found: ${header.author} or ${header.owner}`)
    }

    const templatePath = path.resolve(path.dirname(docPath), header.template)
    if (!fs.existsSync(templatePath)) {
      throw new Error(`Template file not found: ${templatePath}`)
    }

    const templateId = this.metadataRegistry.getRef(templatePath) as Ref<ControlledDocument>
    const category = header.category !== undefined ? this.controlledDocumentCategories.get(header.category) : undefined
    return {
      id,
      metaId,
      class: documents.class.ControlledDocument,
      title: header.title,
      template: templateId,
      code: codeMatch?.[1],
      major: 0,
      minor: 1,

View on GitHub (pinned to 63e28dc964)