hcengineering/platform · error · Error
Issue status not found
Error message
Issue status not found: ${name} What it means
findIssueStatusByName looks up a tracker IssueStatus by exact name and throws when client.findOne returns undefined. The importer requires every referenced status name to exist in the target workspace before mapping imported issues.
Solutions
- Create the missing IssueStatus in the target workspace with the exact name before importing.
- Compare the name string for exact match (case, trailing spaces) against existing statuses via client.findAll(tracker.class.IssueStatus, {}).
- Add a normalization/mapping step that translates source statuses to workspace statuses with a default fallback.
- Pre-fetch all IssueStatus names and validate the import mapping up front, failing early with the full list of missing statuses.
Example fix
// before
const status = await this.client.findOne(tracker.class.IssueStatus, { name, ofAttribute: tracker.attribute.IssueStatus })
if (status === undefined) {
throw new Error('Issue status not found: ' + name)
}
// after
let status = await this.client.findOne(tracker.class.IssueStatus, { name, ofAttribute: tracker.attribute.IssueStatus })
if (status === undefined) {
status = await this.client.findOne(tracker.class.IssueStatus, { name: name.trim().toLowerCase(), ofAttribute: tracker.attribute.IssueStatus })
}
if (status === undefined) {
throw new Error('Issue status not found: ' + name)
} Defensive patterns
Strategy: validation
Validate before calling
const statuses = await client.findAll(tracker.class.IssueStatus, { ofAttribute: tracker.attribute.IssueStatus })
const known = new Set(statuses.map(s => s.name))
const missing = requiredStatusNames.filter(n => !known.has(n))
if (missing.length > 0) throw new Error('Missing issue statuses: ' + missing.join(', ')) Type guard
function hasStatus<T extends { name: string }>(statuses: T[], name: string): T | undefined {
return statuses.find(s => s.name === name)
} Try / catch
try {
const statusRef = await importer.findIssueStatusByName(name)
} catch (err) {
if (err instanceof Error && err.message.startsWith('Issue status not found:')) {
await createMissingStatus(name) // provision then retry
} else throw err
} Prevention
- Pre-create all source-tool statuses in the target workspace before import
- Match names exactly: normalize case/whitespace in your mapping config
- Validate the full status mapping up front instead of lazily per issue
- Keep a default fallback status for unmapped names
When it happens
Trigger: Calling WorkspaceImporter.findIssueStatusByName(name) (directly or during issue import) where no IssueStatus document with that exact name and ofAttribute: tracker.attribute.IssueStatus exists in the workspace.
Common situations: Importing from another tool (Jira/Asana/etc.) whose status names were not pre-created in the target workspace; case/whitespace mismatch between source and target status names; statuses deleted or renamed after mapping was configured.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Attachment not found:
- Cannot import attachment without parent doc
- Card not found, _id
- category not found
- contact not found
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/bde186e8e67264d8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/importer/src/importer/importer.ts:1018
const markup = jsonToMarkup(processedJson)
const result = await this.fileUploader.uploadCollaborativeDoc(collabId, markup)
if (result.success) {
return result.id
}
throw new Error('Failed to upload collaborative document: ' + id)
}
async findIssueStatusByName (name: string): Promise<Ref<IssueStatus>> {
const query: DocumentQuery<Status> = {
name,
ofAttribute: tracker.attribute.IssueStatus
}
const status = await this.client.findOne(tracker.class.IssueStatus, query)
if (status === undefined) {
throw new Error('Issue status not found: ' + name)
}
return status._id
}
async uniqueProjectIdentifier (baseIdentifier: string): Promise<string> {
const projects = await this.client.findAll(tracker.class.Project, {})
const projectsIdentifiers = new Set(projects.map(({ identifier }) => identifier))
let identifier = baseIdentifier
let i = 1
while (projectsIdentifiers.has(identifier)) {
identifier = `${baseIdentifier}${i}`
i++
}
return identifier
}
View on GitHub (pinned to 63e28dc964)