affaan-m/ECC · error · Error

Issue #${issueNumber} cannot be published: review approval r

Error message

Issue #${issueNumber} cannot be published: review approval required (current: ${state.review})

What it means

Thrown by applyPublish after all structural validations pass but the policy requires review approval (policy.review.required) and the issue's current review state is not 'approved' (e.g. 'pending', 'changes-requested', 'none'). This enforces a human gate before publication so unreviewed work cannot be published even if structurally valid.

Source

Thrown at scripts/lib/github-coordination/actions.js:189

    validations,
    missingDependencies,
  };
}

function applyPublish(repo, issueNumber, options = {}, context = {}) {
  assertValidRepo(repo);
  assertValidIssueNumber(issueNumber);
  const policy = context.policy || loadPolicy(context.rootDir || process.cwd(), options.configPath);
  const issue = getIssue(repo, issueNumber, options);
  const state = getCoordinationState(issue, policy);
  const validation = applyValidate(repo, issueNumber, { ...options, dryRun: true }, context, issue);

  if (!validation.ok) {
    throw new Error(`Issue #${issueNumber} is not ready to publish: ${validation.validations.map(entry => `${entry.check}=${entry.ok}`).join(', ')}`);
  }

  if (policy.review && policy.review.required && state.review !== 'approved') {
    throw new Error(`Issue #${issueNumber} cannot be published: review approval required (current: ${state.review})`);
  }

  const nextState = buildIssueStateFromAction(issue, state, 'publish', {
    status: 'published',
    validation: 'passed',
    review: state.review === 'changes-requested' ? state.review : 'approved',
    projectState: 'done',
  }, policy);
  const trackedIssue = {
    ...issue,
    labels: desiredLabelsForState(nextState, policy),
  };

  if (!options.dryRun) {
    const body = mergeIssueBody(issue, nextState, policy);
    editIssue(repo, issueNumber, {
      body,
      addLabels: trackedIssue.labels,

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Obtain review approval on the issue/PR and sync its state (e.g. add the approval label or set review state) before publishing.
  2. If changes were requested, address them and get re-approval to move the state from 'changes-requested' to 'approved'.
  3. Confirm the policy.review.required setting — if review is genuinely optional for this flow, set required:false in the policy config.
  4. Verify the review-state source (labels vs gh API) is correctly populated; a stale/missing label can make an approved issue look unapproved.

Example fix

// before
applyPublish(repo, issueNumber);

// after — check review state first and guide the user
const state = getCoordinationState(getIssue(repo, issueNumber), policy);
if (policy.review?.required && state.review !== 'approved') {
  throw new Error(`Cannot publish: review is '${state.review}'. Get approval, then retry.`);
}
applyPublish(repo, issueNumber);
Defensive patterns

Strategy: validation

Validate before calling

const state = getCoordinationState(getIssue(repo, issueNumber), policy);
if (policy.review && policy.review.required && state.review !== 'approved') {
  throw new Error(`Review approval required (current: ${state.review}).`);
}

Type guard

function isReviewApproved(state, policy) {
  return !(policy && policy.review && policy.review.required) || state.review === 'approved';
}

Try / catch

try {
  applyPublish(repo, issueNumber);
} catch (e) {
  if (/review approval required/.test(e.message)) { requestReview(issueNumber); return; }
  throw e;
}

Prevention

When it happens

Trigger: policy.review.required is true and the issue has no approval; review is in 'changes-requested' state; review was requested but never granted; the review label/state was not synced from GitHub.

Common situations: Team policy mandates approval but the PR/issue skipped review; a reviewer requested changes that were not addressed; review state is tracked via labels and the label is missing/stale.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/6c70fe625a2d44cb. Report an issue: GitHub.