{"record":{"id":"8dd46458424ce4d6","repo":"affaan-m/ECC","slug":"issue-issue-number-is-not-open","errorCode":null,"errorMessage":"Issue #${issue.number} is not open","messagePattern":"Issue #(.+?) is not open","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/github-coordination/state.js","lineNumber":211,"sourceCode":"    action,\n    status: state.status,\n    owner: state.owner || null,\n    branch: state.branch || null,\n    validation: state.validation || 'pending',\n    review: state.review || 'not-requested',\n    project: summarizeProjectProjection(state, policy),\n    dependencies: Array.isArray(state.dependencies) ? state.dependencies : [],\n    tasks: Array.isArray(state.tasks) ? state.tasks : [],\n    labels: normalizeLabels(issue.labels),\n    workItemId: `github-${slugifySegment(repo)}-epic-${issue.number}`,\n    lastActionAt: state.lastActionAt || null,\n    lastSyncAt: state.lastSyncAt || null,\n  };\n}\n\nfunction assertIssueClaimable(issue, state) {\n  if (String(issue.state || '').toLowerCase() !== 'open') {\n    throw new Error(`Issue #${issue.number} is not open`);\n  }\n\n  if (state.status === 'claimed') {\n    throw new Error(`Issue #${issue.number} is already claimed by ${state.owner || 'unknown'}`);\n  }\n}\n\nfunction verifyDependenciesClosed(repo, dependencyNumbers, options = {}, allIssues = null) {\n  if (!Array.isArray(dependencyNumbers) || dependencyNumbers.length === 0) {\n    return [];\n  }\n\n  const issueList = allIssues || listIssues(repo, { ...options, state: 'all', limit: options.limit || 200 });\n  const closed = [];\n  for (const dependencyNumber of dependencyNumbers) {\n    const issue = findIssueByNumber(issueList, dependencyNumber);\n    if (!issue) {\n      process.stderr.write(`[github-coordination] Warning: dependency issue #${dependencyNumber} not found in issue list (may be in a different repo or beyond limit)\\n`);","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/github-coordination/state.js#L193-L229","documentation":"assertIssueClaimable validates that an issue can be claimed: the underlying GitHub issue must be in the 'open' state. It throws when the issue is closed (or has an unexpected state), preventing agents from claiming work on issues that are finished or rejected. A further check rejects issues already claimed by another owner.","triggerScenarios":"Calling applyClaim (directly or via the claim workflow) for an issue whose state is 'closed' — fetched from getIssue/listIssues — or whose state field is missing/case-mismatched in a shim.","commonSituations":"A collaborator closed the issue between listing and claiming, automation auto-closed stale issues, a bot closed issues on branch merge, or a custom shim returns state as 'OPEN' in an unexpected format or omits it.","solutions":["Check the issue on GitHub — if closed intentionally, pick a different issue.","If the issue should be open, reopen it (`gh issue reopen <n> -R <owner>/<name>`) and retry the claim.","Re-sync/re-fetch the issue to get the latest state before claiming.","If using a shim, ensure it returns state as the lowercase string 'open'."],"exampleFix":"// before\napplyClaim('org/repo', 42); // issue 42 is closed\n// after\nrunGh(['issue', 'reopen', '42', '-R', 'org/repo']);\napplyClaim('org/repo', 42);","handlingStrategy":"try-catch","validationCode":"const issue = getIssue(repo, n);\nif (String(issue.state || '').toLowerCase() !== 'open') {\n  throw new Error(`Issue #${n} is ${issue.state}; only open issues can be claimed`);\n}","typeGuard":"const isOpenIssue = (i) => typeof i?.state === 'string' && i.state.toLowerCase() === 'open';","tryCatchPattern":"try {\n  applyClaim(repo, n);\n} catch (e) {\n  if (e.message.endsWith('is not open')) {\n    console.error(`Issue #${n} is closed. Reopen it (gh issue reopen ${n}) or pick another issue.`);\n  } else { throw e; }\n}","preventionTips":["Re-fetch the issue immediately before claiming to get current state.","Filter issue lists to state=open before attempting claims.","Handle races where issues close between listing and claiming.","Ensure shims return state as lowercase 'open'."],"tags":["state","github-issues","concurrency"],"backgroundTag":"invalid-state-transition","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}