{"record":{"id":"37333bbad94b5460","repo":"slopus/happy","slug":"claude-local-launcher-not-found-please-ensure-hap","errorCode":null,"errorMessage":"Claude local launcher not found. Please ensure HAPPY_PROJECT_ROOT is set correctly for development.","messagePattern":"Claude local launcher not found\\. Please ensure HAPPY_PROJECT_ROOT is set correctly for development\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/claude/claudeLocal.ts","lineNumber":254,"sourceCode":"            }\n\n            if (opts.allowedTools && opts.allowedTools.length > 0) {\n                args.push('--allowedTools', opts.allowedTools.join(','));\n            }\n\n            // Add custom Claude arguments\n            if (opts.claudeArgs) {\n                args.push(...opts.claudeArgs)\n            }\n\n            // Add hook settings for session tracking (when available)\n            if (opts.hookSettingsPath) {\n                args.push('--settings', opts.hookSettingsPath);\n                logger.debug(`[ClaudeLocal] Using hook settings: ${opts.hookSettingsPath}`);\n            }\n\n            if (!claudeCliPath || !existsSync(claudeCliPath)) {\n                throw new Error('Claude local launcher not found. Please ensure HAPPY_PROJECT_ROOT is set correctly for development.');\n            }\n\n            // Prepare environment variables\n            // Note: Local mode uses global Claude installation with --session-id flag\n            // Launcher only intercepts fetch for thinking state tracking\n            const env = {\n                ...process.env,\n                ...opts.claudeEnvVars\n            }\n\n            if (opts.mcpServers && Object.keys(opts.mcpServers).length > 0) {\n                ensureLocalProxyBypass(env);\n            }\n\n            logger.debug(`[ClaudeLocal] Spawning launcher: ${claudeCliPath}`);\n            logger.debug(`[ClaudeLocal] Args: ${JSON.stringify(args)}`);\n\n            (async () => {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/claude/claudeLocal.ts#L236-L272","documentation":"In development mode the CLI spawns a locally-built Claude launcher script instead of the packaged one. Before spawning it checks that the resolved claudeCliPath exists on disk; if the path is unset or the file is missing, it throws this error telling the developer to set HAPPY_PROJECT_ROOT correctly.","triggerScenarios":"HAPPY_PROJECT_ROOT is unset, points to a directory that is not a happy repo checkout, or the launcher binary has not been built, so existsSync(claudeCliPath) returns false right before spawning the local Claude process.","commonSituations":"Running the CLI from source (dev mode) in a fresh clone without building; HAPPY_PROJECT_ROOT pointing at the wrong path after moving the repo; running from a packaged install where the dev launcher was never expected to exist.","solutions":["Set HAPPY_PROJECT_ROOT to the absolute path of your happy repo checkout.","Build the local launcher in that checkout (npm install && npm run build).","Verify the launcher file exists: ls $HAPPY_PROJECT_ROOT/<expected launcher path>.","If you are not developing the CLI itself, run the published CLI instead of local mode.","Confirm the path has no trailing-slash/typo issues and the file is executable."],"exampleFix":"// before\nexport HAPPY_PROJECT_ROOT=./happy\n// after\nexport HAPPY_PROJECT_ROOT=/home/me/src/happy && ls $HAPPY_PROJECT_ROOT/packages/happy-cli/dist && npm run build","handlingStrategy":"validation","validationCode":"const root = process.env.HAPPY_PROJECT_ROOT;\nif (!root) throw new Error('HAPPY_PROJECT_ROOT must be set for local development mode');\nif (!existsSync(resolve(root, 'packages/happy-cli/dist'))) throw new Error(`No build found under ${root} — run npm run build`);","typeGuard":"function hasLocalLauncher(p: string | null | undefined): p is string {\n  return typeof p === 'string' && p.length > 0 && existsSync(p);\n}","tryCatchPattern":"try {\n  await runClaude(options);\n} catch (err) {\n  if ((err as Error).message.includes('Claude local launcher not found')) {\n    console.error('Dev launcher missing. Set HAPPY_PROJECT_ROOT to your happy checkout and build it.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Export HAPPY_PROJECT_ROOT in your dev shell profile or direnv config.","Always build after cloning or pulling before using local mode.","Use the published CLI unless actively developing the CLI itself.","Add a pre-flight existsSync check in wrapper scripts."],"tags":["configuration","filesystem","development"],"backgroundTag":"missing-env-var","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}