hcengineering/platform · error · Error

Failed to find target project type: ${typeId}

Error message

Failed to find target project type: ${typeId}

What it means

This error is thrown by the createVacancy function in the CreateVacancy.svelte component of the Huly recruit plugin when the selected vacancy (project) type is missing at submit time. The component reads typeId from the shared $selectedTypeStore and derives typeType via $typeStore.get(typeId); if either is undefined, the vacancy cannot be typed/validated, so the function aborts before querying the Sequence and creating the Vacancy document. It is a guard against creating a Vacancy without a valid ProjectType reference.

Source

Thrown at plugins/recruit-resources/src/components/CreateVacancy.svelte:226

    }

    await client.addCollection(tracker.class.Issue, space, parent, tracker.class.Issue, 'subIssues', data, resId)
    if ((template.labels?.length ?? 0) > 0) {
      const tagElements = await client.findAll(tags.class.TagElement, { _id: { $in: template.labels } })
      for (const label of tagElements) {
        await client.addCollection(tags.class.TagReference, space, resId, tracker.class.Issue, 'labels', {
          title: label.title,
          color: label.color,
          tag: label._id
        })
      }
    }
    return resId
  }

  async function createVacancy (): Promise<void> {
    if (typeId === undefined || typeType === undefined) {
      throw Error(`Failed to find target project type: ${typeId}`)
    }

    const sequence = await client.findOne(core.class.Sequence, { attachedTo: recruit.class.Vacancy })
    if (sequence === undefined) {
      throw new Error('sequence object not found')
    }

    const incResult = await client.update(sequence, { $inc: { sequence: 1 } }, true)
    const data: Data<Vacancy> = {
      ...vacancyData,
      name: name.trim(),
      description: template?.shortDescription ?? '',
      fullDescription: null,
      private: false,
      archived: false,
      number: (incResult as any).object.sequence,
      company,
      members,

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Select a vacancy/project type in the creation dialog before submitting (the type selector must resolve a ProjectType).
  2. Refresh the page/re-open the dialog so selectedTypeStore and typeStore re-sync with the server.
  3. Verify the ProjectType still exists and is not hidden/archived: query task.class.ProjectType by the id shown in the error message.
  4. If developing an integration, set $selectedTypeStore to a valid Ref<ProjectType> that is present in $typeStore before invoking createVacancy.
  5. Check for version mismatches between task/task-resources plugins where typeStore population may have changed.

Example fix

// before
async function createVacancy (): Promise<void> {
  if (typeId === undefined || typeType === undefined) {
    throw Error(`Failed to find target project type: ${typeId}`)
  }
  ...
}
// after
async function createVacancy (): Promise<void> {
  if (typeId === undefined) {
    // surface a UI validation message instead of throwing deep in the handler
    showError(getEmbeddedLabel('Please select a vacancy type'))
    return
  }
  const typeType = $typeStore.get(typeId)
  if (typeType === undefined) {
    showError(getEmbeddedLabel('Selected vacancy type is unavailable; please reselect it'))
    return
  }
  ...
}
Defensive patterns

Strategy: validation

Validate before calling

// Run before calling createVacancy / enabling the submit button
import { get } from 'svelte/store'
import { selectedTypeStore, typeStore } from '@hcengineering/task-resources'

function canCreateVacancy (): boolean {
  const typeId = get(selectedTypeStore)
  if (typeId === undefined) return false
  return get(typeStore).get(typeId) !== undefined
}

Type guard

function hasProjectType (
  typeId: Ref<ProjectType> | undefined
): typeId is Ref<ProjectType> & string {
  return typeId !== undefined && $typeStore.get(typeId) !== undefined
}

Try / catch

try {
  await createVacancy()
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Failed to find target project type')) {
    showPopup(MessageBox, {
      label: getEmbeddedLabel('Please select a valid vacancy type before saving')
    })
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: Clicking the create/save button in the vacancy creation popup while: (1) no project type has been selected yet (typeId === undefined because selectedTypeStore is empty), or (2) a typeId exists but is not present in typeStore (e.g. the type was deleted, filtered out by descriptors, or the typeStore query has not populated yet), so typeType === undefined.

Common situations: User opens the Create Vacancy dialog from a context that did not preselect a vacancy type; the ProjectType referenced by the store was deleted/archived by another user or removed after a workspace upgrade; a race where the typeStore live query has not yet loaded results before submit; embedding the component without initializing selectedTypeStore.

Related errors


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