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
- Select a vacancy/project type in the creation dialog before submitting (the type selector must resolve a ProjectType).
- Refresh the page/re-open the dialog so selectedTypeStore and typeStore re-sync with the server.
- Verify the ProjectType still exists and is not hidden/archived: query task.class.ProjectType by the id shown in the error message.
- If developing an integration, set $selectedTypeStore to a valid Ref<ProjectType> that is present in $typeStore before invoking createVacancy.
- 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
- Disable the submit button until a project type is selected and resolvable in typeStore.
- Keep selectedTypeStore initialized (e.g. default to the first active ProjectType) when opening the dialog.
- Re-check that referenced ProjectTypes are not deleted/archived before listing them as selectable options.
- Subscribe to the typeStore live query and clear an outdated selection if its type disappears.
- In tests/integrations, seed a valid ProjectType and set selectedTypeStore before exercising creation flows.
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
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- Message id is required
- Message id is required
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/ad4e31b51b1741af.
Report an issue: GitHub.