{"record":{"id":"d8ca6802d84bcc13","repo":"affaan-m/ECC","slug":"issue-issue-number-is-already-claimed-by-sta","errorCode":null,"errorMessage":"Issue #${issue.number} is already claimed by ${state.owner || 'unknown'}","messagePattern":"Issue #(.+?) is already claimed by (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/github-coordination/state.js","lineNumber":215,"sourceCode":"    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`);\n    } else if (String(issue.state || '').toLowerCase() === 'closed') {\n      closed.push(dependencyNumber);\n    }\n  }","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/github-coordination/state.js#L197-L233","documentation":"Thrown by assertIssueClaimable() when the issue is open but the coordination state already records status === 'claimed'. The message identifies the current owner (or 'unknown' if state.owner is missing) so the caller can coordinate rather than double-claim.","triggerScenarios":"assertIssueClaimable(issue, state) where state.status === 'claimed'. state is typically returned by getCoordinationState() which parses the embedded coordination block from the issue body.","commonSituations":"Two agents race to claim the same issue; a previous claim's comment is still embedded in the issue body; the claim was released locally but the issue body still shows status: claimed; manual edit of the coordination marker left status as 'claimed'.","solutions":["Confirm the current owner: read the coordination block in the issue body or call getCoordinationState(issue).","If the prior claim is stale, release it first (set status back to 'available' and post the coordination comment) before retrying.","If actively owned, pick a different issue or wait for the owner to publish/release.","Add a pre-check: if (state.status === 'claimed') skip or queue."],"exampleFix":"// before\nassertIssueClaimable(issue, state);\n\n// after\nif (state.status === 'claimed') {\n  console.log(`#${issue.number} already owned by ${state.owner || 'unknown'}; skipping`);\n  return null;\n}\nassertIssueClaimable(issue, state);","handlingStrategy":"validation","validationCode":"function isClaimable(issue, state) {\n  return String(issue.state || '').toLowerCase() === 'open'\n    && state.status !== 'claimed';\n}\nif (!isClaimable(issue, state)) {\n  console.log(`#${issue.number} owned by ${state.owner || 'unknown'}`);\n}","typeGuard":"function isUnclaimed(state) {\n  return state && state.status !== 'claimed';\n}","tryCatchPattern":"try {\n  assertIssueClaimable(issue, state);\n} catch (err) {\n  if (/already claimed/) {\n    return { skipped: true, owner: state.owner };\n  }\n  throw err;\n}","preventionTips":["Use a single coordination dispatcher (e.g. serialized queue) to avoid races.","Refresh getCoordinationState(issue) right before claiming.","Build a release/unclaim flow that clears status: claimed in the issue body."],"tags":["github","state","coordination","concurrency"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}