affaan-m/ECC · error · Error
Issue #${issue.number} is not open
Error message
Issue #${issue.number} is not open What it means
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.
Source
Thrown at scripts/lib/github-coordination/state.js:211
action,
status: state.status,
owner: state.owner || null,
branch: state.branch || null,
validation: state.validation || 'pending',
review: state.review || 'not-requested',
project: summarizeProjectProjection(state, policy),
dependencies: Array.isArray(state.dependencies) ? state.dependencies : [],
tasks: Array.isArray(state.tasks) ? state.tasks : [],
labels: normalizeLabels(issue.labels),
workItemId: `github-${slugifySegment(repo)}-epic-${issue.number}`,
lastActionAt: state.lastActionAt || null,
lastSyncAt: state.lastSyncAt || null,
};
}
function assertIssueClaimable(issue, state) {
if (String(issue.state || '').toLowerCase() !== 'open') {
throw new Error(`Issue #${issue.number} is not open`);
}
if (state.status === 'claimed') {
throw new Error(`Issue #${issue.number} is already claimed by ${state.owner || 'unknown'}`);
}
}
function verifyDependenciesClosed(repo, dependencyNumbers, options = {}, allIssues = null) {
if (!Array.isArray(dependencyNumbers) || dependencyNumbers.length === 0) {
return [];
}
const issueList = allIssues || listIssues(repo, { ...options, state: 'all', limit: options.limit || 200 });
const closed = [];
for (const dependencyNumber of dependencyNumbers) {
const issue = findIssueByNumber(issueList, dependencyNumber);
if (!issue) {
process.stderr.write(`[github-coordination] Warning: dependency issue #${dependencyNumber} not found in issue list (may be in a different repo or beyond limit)\n`);View on GitHub (pinned to 01e15490f0)
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'.
Example fix
// before
assertIssueClaimable(issue, state);
// after
if (String(issue.state || '').toLowerCase() !== 'open') {
throw new Error(`Cannot claim #${issue.number}: issue is ${issue.state}`);
}
assertIssueClaimable(issue, state); Defensive patterns
Strategy: validation
Validate before calling
function isOpenIssue(issue) {
return Boolean(issue) && String(issue.state || '').toLowerCase() === 'open';
}
if (!isOpenIssue(issue)) {
throw new Error(`Refusing to act: #${issue && issue.number} is ${issue && issue.state}`);
} Type guard
function isOpenIssue(issue) {
return issue != null && typeof issue === 'object'
&& String(issue.state || '').toLowerCase() === 'open';
} Try / catch
try {
assertIssueClaimable(issue, state);
} catch (err) {
if (/is not open/.test(err.message)) {
return { skipped: true, reason: 'issue-closed' };
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Issue #${issue.number} is already claimed by ${state.owner |
- ${flagName} requires a value
- Unknown argument: ${arg}
- Missing issue number.
- Unknown command: ${options.command}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/8dd46458424ce4d6.
Report an issue: GitHub.