alibaba/open-code-review · error · Error

Could not locate ${REL}; searched roots: ${roots.join(', ')}

Error message

Could not locate ${REL}; searched roots: ${roots.join(', ')}

What it means

The GitHub Action's checkpoint-restoration step cannot find the helper script scripts/github-actions/post-review-comments.js in any of its search roots (GITHUB_ACTION_PATH, GITHUB_WORKSPACE). The step throws deliberately instead of continuing with a missing helper, because checkpoint logic cannot run without it. The comment above confirms the outage is non-fatal to the overall review, hence the surrounding try block.

Source

Thrown at action.yml:512

            core.setOutput('range_summary', summary);
            core.setOutput('checkpoint_before', range.checkpointBefore || '');
            core.setOutput('ancestry', range.ancestry || '');
            core.setOutput('source_run', range.sourceRun || '');
            core.setOutput('config_fingerprint', fingerprint);
            core.setOutput('checkpoint_carry', carry);
            core.info(`[checkpoint] reviewing ${summary}`);
          };

          // This step only chooses where the review starts, and every failure it
          // can hit has the same safe answer: review the whole merge-base range.
          // So nothing in here may fail the job — a missing helper or an API
          // outage must not block a review the action can still perform.
          try {
            // Same helper lookup as the posting step below.
            const REL = 'scripts/github-actions/post-review-comments.js';
            const roots = [process.env.GITHUB_ACTION_PATH, process.env.GITHUB_WORKSPACE].filter(Boolean);
            const helper = roots.map(r => path.resolve(r, REL)).find(p => fs.existsSync(p));
            if (!helper) throw new Error(`Could not locate ${REL}; searched roots: ${roots.join(', ')}`);
            const { resolveCheckpointRange, readCheckpointComment } = require(helper);

            const sha256 = (buf) => crypto.createHash('sha256').update(buf).digest('hex');
            let ruleUnverified = false;

            // `rule` names a JSON file that OCR reads off the workspace at review
            // time (rules.NewResolver only touches disk when the path is non-empty;
            // the default rule set is embedded in the binary and so already moves
            // with OCR_VERSION_ACTUAL). Fingerprinting the *path* alone would let an
            // edit to that file narrow the next range under rules the earlier
            // commits were never reviewed against, so hash the contents too.
            let ruleDigest = 'none';
            const rulePath = process.env.OCR_RULE_PATH || '';
            if (rulePath) {
              try {
                ruleDigest = sha256(fs.readFileSync(path.resolve(process.env.GITHUB_WORKSPACE || '.', rulePath)));
              } catch (e) {
                // Cannot prove the rules are unchanged -> do not narrow. OCR itself

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Verify the repo is checked out before this step (actions/checkout runs first) so GITHUB_WORKSPACE contains scripts/github-actions/post-review-comments.js.
  2. Ensure the helper script is committed/packaged with the action or bundled into the dist output the action ships.
  3. Check that GITHUB_ACTION_PATH or GITHUB_WORKSPACE is set for the runner job; if running in a container, mount the workspace accordingly.
  4. Treat the throw as expected non-fatal: keep the step in try/catch so a missing checkpoint helper degrades gracefully instead of failing the review.

Example fix

// before
if (!helper) throw new Error(`Could not locate ${REL}; searched roots: ${roots.join(', ')}`);
// after
if (!helper) {
  core.warning(`Skipping checkpoint restore: ${REL} not found in ${roots.join(', ')}`);
  return; // or fall through without checkpoint logic
}
Defensive patterns

Strategy: fallback

Validate before calling

const REL = 'scripts/github-actions/post-review-comments.js';
const roots = [process.env.GITHUB_ACTION_PATH, process.env.GITHUB_WORKSPACE].filter(Boolean);
const helper = roots.map(r => path.resolve(r, REL)).find(p => fs.existsSync(p));
const helperAvailable = Boolean(helper);
if (!helperAvailable) core.warning(`checkpoint helper missing; searched: ${roots.join(', ')}`);

Type guard

function helperExists(roots) {
  return typeof roots.find(r => fs.existsSync(path.resolve(r, 'scripts/github-actions/post-review-comments.js'))) === 'string';
}

Try / catch

try {
  const helper = roots.map(r => path.resolve(r, REL)).find(p => fs.existsSync(p));
  if (!helper) throw new Error(`Could not locate ${REL}`);
  const { resolveCheckpointRange } = require(helper);
} catch (err) {
  core.warning(`Checkpoint restore skipped: ${err.message}`);
}

Prevention

When it happens

Trigger: GITHUB_ACTION_PATH and GITHUB_WORKSPACE are unset or empty (both filtered out, leaving zero roots), or the JS bundle was not copied into the action image/workspace at scripts/github-actions/post-review-comments.js.

Common situations: Action packaged with dist-only layout while scripts/ is excluded from the published action; a composite step running in a container or workspace with a different checkout path; fork/renamed repo where the helper file was moved or deleted; runs where the repo is not checked out (actions/checkout missing) so GITHUB_WORKSPACE lacks scripts.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/6cad83790d26c8b7. Report an issue: GitHub.