{"record":{"id":"ab4ecdf76218bb84","repo":"ruvnet/ruflo","slug":"statusline-generator-could-not-locate-claude-hel","errorCode":null,"errorMessage":"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).","messagePattern":"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\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/init/statusline-generator.ts","lineNumber":133,"sourceCode":"    for (let i = 0; i < 6; i++) {\n      try {\n        const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'));\n        if (pkg && pkg.name === '@claude-flow/cli') {\n          const candidate = path.join(dir, '.claude', 'helpers', 'statusline.cjs');\n          if (fs.existsSync(candidate)) {\n            helperPackageRoot = dir;\n            helperContent = fs.readFileSync(candidate, 'utf-8');\n            break;\n          }\n        }\n      } catch { /* keep climbing */ }\n      const parent = path.dirname(dir);\n      if (parent === dir) break;\n      dir = parent;\n    }\n  }\n  if (helperContent === null) {\n    throw new Error(\n      'statusline-generator: could not locate .claude/helpers/statusline.cjs '\n      + 'relative to @claude-flow/cli. This is a packaging bug — the helper '\n      + 'must ship with the CLI (see package.json files entry for .claude).'\n    );\n  }\n\n  // Two known interpolation points — both single-line, both idempotent\n  // string replacements. If a future edit to the helper renames either\n  // token, this replace() is a no-op and the fallback default (15,\n  // whatever the helper hard-codes) ships. Add a paired test in\n  // statusline-cost-display.test.ts before changing either token.\n  helperContent = helperContent.replace(/maxAgents: \\d+,/, `maxAgents: ${maxAgents},`);\n  helperContent = helperContent.replace(\n    /const BAKED_INSTALL_ROOT = \"[^\"]*\";/,\n    `const BAKED_INSTALL_ROOT = ${JSON.stringify(helperPackageRoot)};`,\n  );\n  // Only overwrite the helper's baked version if OURS resolves higher.\n  // Otherwise the substitution could DOWNGRADE (test environments where","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/init/statusline-generator.ts#L115-L151","documentation":"The statusline generator walks up the directory tree from the CLI package root looking for .claude/helpers/statusline.cjs; if the file is never found it throws, because the helper is required to ship inside the published @claude-flow/cli package (its package.json `files` entry must include .claude). The error explicitly labels itself a packaging bug — it means the installed artifact is missing an asset, not that user input was wrong.","triggerScenarios":"Installing from a tarball or fork whose package.json `files` array (or .npmignore) excluded the dot-directory `.claude`; a bundler (esbuild/webpack/vercel ncc) that stripped non-code assets when repacking; a corrupted or partial npm install where node_modules/@claude-flow/cli/.claude was deleted; running from a source checkout that never copied the helper into dist.","commonSituations":"Companies vendoring the CLI through an internal registry that repacks with different files rules; pnpm strict symlink layouts combined with custom deploy scripts; npm cache corruption after an interrupted install; forks that renamed .claude and forgot this lookup; Docker images built with `npm prune --production` plus an aggressive asset-stripping layer.","solutions":["Verify the file exists: ls node_modules/@claude-flow/cli/.claude/helpers/statusline.cjs — if missing, reinstall cleanly (`npm cache clean --force && rm -rf node_modules package-lock.json && npm install`)","Pin to a known-good published version: `npm install @claude-flow/cli@latest` rather than a fork or local tarball","If you build/publish the package yourself, ensure package.json `files` includes \".claude\" and that the helper is present in the tarball (`npm pack` then `tar -tzf *.tgz | grep statusline`)","If a published release is genuinely missing the asset, report it upstream with your install method — the message says 'see package.json files entry for .claude'"],"exampleFix":"// before — publishing pipeline drops dot-directories\n// package.json\n\"files\": [\"dist\", \"src\", \"README.md\"]\n\n// after — helper ships with the CLI\n\"files\": [\"dist\", \"src\", \"README.md\", \".claude\"]","handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm the helper asset shipped with the install\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst helper = join(\n  require.resolve('@claude-flow/cli').replace(/\\/[^/]*$/, ''),\n  '.claude/helpers/statusline.cjs'\n);\nif (!existsSync(helper)) console.warn('statusline helper missing — install is incomplete');","typeGuard":null,"tryCatchPattern":"try {\n  const out = generateStatusline(cfg);\n  fs.writeFileSync(statusPath, out);\n} catch (err) {\n  // Packaging bug — degrade gracefully: skip the statusline rather than abort init\n  console.warn(`statusline skipped: ${(err as Error).message}`);\n}","preventionTips":["Pin @claude-flow/cli to an exact published version in package.json/lockfile","Add a CI smoke test that runs the init/statusline command on a clean install","If you fork/repack the CLI, keep `.claude` in package.json `files` and verify with npm pack"],"tags":["packaging","install","statusline","npm","missing-asset"],"backgroundTag":"missing-package-file","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}