affaan-m/ECC · error · Error
invalid issueNumber: expected positive integer, got ${JSON.s
Error message
invalid issueNumber: expected positive integer, got ${JSON.stringify(issueNumber)} What it means
Thrown by assertValidIssueNumber when issueNumber is not a finite positive integer. GitHub issue numbers are positive integers; negatives, zero, fractions, NaN, or non-numeric strings all make gh issue view fail or target the wrong issue. The guard uses Number.isFinite + > 0 + Number.isInteger to reject all malformed inputs before any gh call.
Source
Thrown at scripts/lib/github-coordination/actions.js:27
buildIssueStateFromAction,
desiredLabelsForState,
getCoordinationState,
summarizeStateForOutput,
syncIssueLabels,
verifyDependenciesClosed,
} = require('./state');
const { upsertCoordinationWorkItem } = require('./store');
const { extractIssueReferences, extractTasks } = require('./parsing');
function assertValidRepo(repo) {
if (typeof repo !== 'string' || !repo.trim()) {
throw new Error(`invalid repo: expected non-empty string, got ${JSON.stringify(repo)}`);
}
}
function assertValidIssueNumber(issueNumber) {
if (!Number.isFinite(issueNumber) || issueNumber <= 0 || !Number.isInteger(issueNumber)) {
throw new Error(`invalid issueNumber: expected positive integer, got ${JSON.stringify(issueNumber)}`);
}
}
function staleCoordinationLabels(issue, nextLabels, policy) {
const epicLabel = policy.labels && policy.labels.epic;
return normalizeLabels(issue.labels).filter(l =>
(l.startsWith('coordination:') || l === epicLabel) && !nextLabels.includes(l)
);
}
// applyClaim performs a read (getIssue) → check (assertIssueClaimable) → write
// (editIssue) sequence that is NOT atomic. Two concurrent callers can both read
// an unclaimed issue, pass the check, and both succeed — resulting in a
// double-claim. A code-review finding suggested fixing this via
// context.store.acquireLock(repo, issueNumber), but that API does not exist in
// store.js; adding a call to it would throw at runtime. Left as-is until a
// locking primitive is available — callers should prevent races via external
// serialization (e.g. a serialized job queue or GitHub branch-protection rule).View on GitHub (pinned to 01e15490f0)
Solutions
- Pass a positive integer (e.g. 42) — convert and validate before calling.
- Strip leading '#' and parse: const n = Number.parseInt(String(raw).replace(/^#/, ''), 10); assert Number.isInteger(n) && n > 0.
- Validate at the CLI/config boundary so the coordination functions receive clean numbers.
- Add a unit test with 0, -1, 3.5, NaN, 'abc' to confirm the guard.
Example fix
// before
applyPublish(repo, rawIssue);
// after — coerce and validate
const issueNumber = Number.parseInt(String(rawIssue).replace(/^#/, ''), 10);
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
throw new Error(`issue number must be a positive integer, got ${rawIssue}`);
}
applyPublish(repo, issueNumber); Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
throw new Error(`issueNumber must be a positive integer, got ${JSON.stringify(issueNumber)}`);
} Type guard
function isPositiveInt(n) {
return Number.isInteger(n) && n > 0;
} Try / catch
try {
applyPublish(repo, issueNumber);
} catch (e) {
if (/invalid issueNumber/.test(e.message)) { console.error('Pass a positive integer issue number'); process.exit(2); }
throw e;
} Prevention
- Strip '#' and parse issue refs to integers at the input boundary.
- Never pass 0, -1, NaN, or strings into coordination functions.
- Validate numeric CLI args before calling the API.
When it happens
Trigger: Passing issueNumber: 0, -5, 3.5, NaN, 'abc', or undefined; reading the number from a string ('#42') without stripping the '#'; parseInt on an empty string yielding NaN.
Common situations: CLI arg parsed as string not converted to number; issue ref like '#42' passed raw; URL param not validated; off-by-one or default 0 sentinel leaked into the call.
Related errors
- invalid repo: expected non-empty string, got ${JSON.stringif
- Invalid issue number: ${value}
- claim requires an owner.
- move requires a work item id.
- Issue #${issueNumber} is not ready to publish: ${validation.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/0045097ade6d8beb.
Report an issue: GitHub.