ruvnet/ruflo · error · Error

statusline-generator: could not locate .claude/helpers/statu

Error message

statusline-generator: could not locate .claude/helpers/statusline.cjs relative to @claude-flow/cli. This is a packaging bug — the helper must ship with the CLI (see package.json files entry for .claude).

What it means

Thrown by generateStatusline() when neither the createRequire.resolve path nor the 6-step __dirname walk-up fallback could find `.claude/helpers/statusline.cjs` inside the resolved @claude-flow/cli package root. The helper file is the single source of truth for the statusline template (read since #2679); without it the generator cannot substitute maxAgents or bakedVersion. The message itself names it a packaging bug because the file must be present in the published tarball via the package.json `files` entry.

Source

Thrown at v3/@claude-flow/cli/src/init/statusline-generator.ts:133

    for (let i = 0; i < 6; i++) {
      try {
        const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'));
        if (pkg && pkg.name === '@claude-flow/cli') {
          const candidate = path.join(dir, '.claude', 'helpers', 'statusline.cjs');
          if (fs.existsSync(candidate)) {
            helperPackageRoot = dir;
            helperContent = fs.readFileSync(candidate, 'utf-8');
            break;
          }
        }
      } catch { /* keep climbing */ }
      const parent = path.dirname(dir);
      if (parent === dir) break;
      dir = parent;
    }
  }
  if (helperContent === null) {
    throw new Error(
      'statusline-generator: could not locate .claude/helpers/statusline.cjs '
      + 'relative to @claude-flow/cli. This is a packaging bug — the helper '
      + 'must ship with the CLI (see package.json files entry for .claude).'
    );
  }

  // Two known interpolation points — both single-line, both idempotent
  // string replacements. If a future edit to the helper renames either
  // token, this replace() is a no-op and the fallback default (15,
  // whatever the helper hard-codes) ships. Add a paired test in
  // statusline-cost-display.test.ts before changing either token.
  helperContent = helperContent.replace(/maxAgents: \d+,/, `maxAgents: ${maxAgents},`);
  helperContent = helperContent.replace(
    /const BAKED_INSTALL_ROOT = "[^"]*";/,
    `const BAKED_INSTALL_ROOT = ${JSON.stringify(helperPackageRoot)};`,
  );
  // Only overwrite the helper's baked version if OURS resolves higher.
  // Otherwise the substitution could DOWNGRADE (test environments where

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Verify the package.json `files` array includes `.claude` and republish: `npm pack` and inspect the tarball for `.claude/helpers/statusline.cjs`.
  2. Run from a source checkout instead of the broken install: `node v3/@claude-flow/cli/dist/src/init/statusline-generator.js` or `pnpm --filter @claude-flow/cli build`.
  3. If pinned to a known-bad published version, upgrade: `npm i -g @claude-flow/cli@latest` (the walk-up fallback only helps when the source tree is reachable).
  4. As a last resort, copy the committed helper into the install dir: place `.claude/helpers/statusline.cjs` adjacent to the resolved package.json (diagnostic only — fix the publish, do not ship this patch).

Example fix

// before (package.json missing the entry)
"files": ["dist", "src", "README.md"]
// after
"files": ["dist", "src", ".claude", "README.md"]
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import { createRequire } from 'node:module';
function helperShips(): boolean {
  try {
    const r = createRequire(import.meta.url);
    const pkgJson = r.resolve('@claude-flow/cli/package.json');
    const helper = path.join(path.dirname(pkgJson), '.claude', 'helpers', 'statusline.cjs');
    return existsSync(helper);
  } catch { return false; }
}
if (!helperShips()) console.warn('install is missing the statusline helper — republish with .claude in files');

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Invoking the statusline generator (the `hooks statusline` command, or the Claude Code statusline hook that shells out to it) after a publish that omitted `.claude/` from the npm tarball; running inside a container/CI image built from a stripped dist checkout; or running from an ephemeral `npx` cache whose hash directory lacks the helper because the resolved version pre-dates the file being added.

Common situations: A release was cut without `.claude` in package.json `files`; a bundler/tree-shake step stripped the `.claude` directory; a fork or vendored copy of the CLI dropped the helpers folder; running against a dist-only Docker image that did not copy `.claude`.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/ab4ecdf76218bb84. Report an issue: GitHub.