{"record":{"id":"27bed10fc01d3e8e","repo":"hcengineering/platform","slug":"no-status-found-for-gh-issue-status-pr-state","errorCode":null,"errorMessage":"No status found for GH issue status ${pr.state} ${pr.stateReason}","messagePattern":"No status found for GH issue status (.+?) (.+?)","errorType":"error_code","errorClass":"PlatformError","httpStatus":null,"severity":"error","filePath":"services/github/pod-github/src/sync/utils.ts","lineNumber":207,"sourceCode":"  const canceled = (): Status | undefined => statuses.find((it) => it.category === task.statusCategory.Lost)\n  const completed = (): Status | undefined => statuses.find((it) => it.category === task.statusCategory.Won)\n\n  let result: IssueStatus | undefined\n\n  if (pr.state === 'OPEN' && pr.stateReason == null) {\n    result = unstarted() ?? todo() ?? active()\n  } else if (pr.state === 'OPEN' && pr.stateReason === GithubIssueStateReason.Reopened) {\n    result = active()\n  } else if (pr.state === 'CLOSED' && pr.stateReason === GithubIssueStateReason.NotPlanned) {\n    result = canceled()\n  } else if (pr.state === 'CLOSED' || pr.state === 'MERGED') {\n    result = completed()\n  } else {\n    // By default put into backlog\n    result = unstarted() ?? todo() ?? active()\n  }\n  if (result === undefined) {\n    throw new PlatformError(unknownStatus(`No status found for GH issue status ${pr.state} ${pr.stateReason}`))\n  }\n  return result\n}\n\n/**\n * @public\n */\nexport class SyncRunner {\n  eventSync = new Map<string, Promise<void>>()\n\n  async exec<T>(id: string, op: () => Promise<T>): Promise<T> {\n    await this.eventSync.get(id)\n    const promise = op()\n    this.eventSync.set(\n      id,\n      promise.then(() => {})\n    )\n    try {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/github/pod-github/src/sync/utils.ts#L189-L225","documentation":"During GitHub issue/PR sync, guessStatus maps a GitHub issue state (open/closed) plus stateReason to an internal project status (done, unstarted, todo, active, etc.). If every mapping helper returns undefined — i.e. the workspace's project statuses contain none of the recognized statuses — this unknownStatus PlatformError is thrown with the GH state and stateReason embedded.","triggerScenarios":"Syncing a GitHub issue whose state/stateReason combination (e.g. closed with an unusual stateReason, or state 'all'/'unknown' from an API response) cannot be matched, in a project whose status list lacks the standard done/todo/backlog/in-progress statuses.","commonSituations":"Projects created with a customized status set (renamed/deleted default statuses) so no recognized status matches; syncing into a bare or misconfigured project; GitHub API returning unexpected stateReason values; partially-initialized projects missing statuses.","solutions":["Add/restore the standard statuses (done/todo/in-progress/backlog or the ones the mapper recognizes) to the target project.","Check the sync target project's status configuration and rename custom statuses back to recognized defaults.","Catch the error per-issue so one unmappable issue doesn't abort the whole sync, and inspect its state/stateReason values.","Update the mapper or project template if new GitHub stateReason values need support."],"exampleFix":"// before\nconst status = guessStatus(pr, statuses) // throws if none match\n// after\ntry {\n  const status = guessStatus(pr, statuses)\n} catch (err) {\n  console.warn(`Unmapped GH status ${pr.state}/${pr.stateReason}, defaulting to backlog`)\n  const status = unstarted() ?? statuses[0]\n}","handlingStrategy":"try-catch","validationCode":"const recognized = statuses.some(s => ['done', 'todo', 'unstarted', 'active', 'backlog'].includes(s.name))\nif (!recognized) {\n  console.warn('Project statuses unrecognized by GH mapper; sync may fail')\n}","typeGuard":"function hasMappableStatus(statuses: Status[]): boolean {\n  return statuses.some(s => s.ofCategory !== undefined) && statuses.length > 0\n}","tryCatchPattern":"try {\n  status = guessStatus(pr, statuses)\n} catch (err) {\n  if (err.message.includes('No status found for GH issue status')) {\n    console.warn(`Defaulting to first status for ${pr.state}/${pr.stateReason}`)\n    status = unstarted() ?? statuses[0]\n  } else throw err\n}","preventionTips":["Keep the default status set (done/todo/in-progress/backlog) in projects targeted by GitHub sync.","Per-issue error isolation so one unmappable issue doesn't abort the whole sync run.","Log state/stateReason on failure to spot new GitHub values needing mapper support."],"tags":["github","sync","status-mapping","integration"],"backgroundTag":"status-mapping-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}