{"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":"Error","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/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/github-coordination/state.js#L193-L229","documentation":"Thrown by assertIssueClaimable() in scripts/lib/github-coordination/state.js when an attempt is made to claim a GitHub issue whose state is not 'open' (case-insensitive). The coordination workflow only allows claiming open issues.","triggerScenarios":"assertIssueClaimable(issue, state) is invoked with an issue object whose issue.state (lowercased) is 'closed' or any value other than 'open'. Common entry points: claim commands, sync workflows that re-check claimability.","commonSituations":"Issue was closed by a maintainer after the local cache was built; a stale issue number was passed; the issue was converted to a discussion; race condition where another agent closed it between fetch and claim.","solutions":["Re-fetch the issue to confirm its current state: gh issue view <number> --repo <repo> --json state,number.","If the issue is genuinely closed, pick a different open issue or reopen it (with maintainer approval) before claiming.","Refresh the local issue list (listIssues) before retrying the claim to avoid stale state.","Guard the claim call with a pre-check on issue.state === 'open'."],"exampleFix":"// before\nassertIssueClaimable(issue, state);\n\n// after\nif (String(issue.state || '').toLowerCase() !== 'open') {\n  throw new Error(`Cannot claim #${issue.number}: issue is ${issue.state}`);\n}\nassertIssueClaimable(issue, state);","handlingStrategy":"validation","validationCode":"function isOpenIssue(issue) {\n  return Boolean(issue) && String(issue.state || '').toLowerCase() === 'open';\n}\nif (!isOpenIssue(issue)) {\n  throw new Error(`Refusing to act: #${issue && issue.number} is ${issue && issue.state}`);\n}","typeGuard":"function isOpenIssue(issue) {\n  return issue != null && typeof issue === 'object'\n    && String(issue.state || '').toLowerCase() === 'open';\n}","tryCatchPattern":"try {\n  assertIssueClaimable(issue, state);\n} catch (err) {\n  if (/is not open/.test(err.message)) {\n    return { skipped: true, reason: 'issue-closed' };\n  }\n  throw err;\n}","preventionTips":["Always re-fetch the issue (or use listIssues with state:'open') immediately before claiming.","Treat the local issue list as stale; verify issue.state in the caller.","Build idempotent claim logic so re-running after a state change is safe."],"tags":["github","state","coordination"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}