{"record":{"id":"87a0bbf6f9bdf20f","repo":"Yeachan-Heo/oh-my-codex","slug":"notify-hook-js-not-found-at-notifyhook","errorCode":null,"errorMessage":"notify-hook.js not found at ${notifyHook}","messagePattern":"notify-hook\\.js not found at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/tmux-hook.ts","lineNumber":453,"sourceCode":"\n  console.log('tmux-hook config is valid.');\n  console.log(`Resolved target pane: ${resolved.target}`);\n  console.log(`Mode gating: ${config.allowed_modes.join(', ')}`);\n  if (!config.enabled) {\n    console.log('Note: config is currently disabled (`enabled: false`).');\n  }\n}\n\nasync function testTmuxHook(args: string[]): Promise<void> {\n  const cwd = process.cwd();\n  const { initResult } = await loadConfigForCommand('test', cwd);\n  if (initResult?.usedPlaceholderTarget) {\n    console.log('Proceeding with placeholder target; notify-hook may log `invalid_config` skips.');\n  }\n  const pkgRoot = getPackageRoot();\n  const notifyHook = join(pkgRoot, 'dist', 'scripts', 'notify-hook.js');\n  if (!existsSync(notifyHook)) {\n    throw new Error(`notify-hook.js not found at ${notifyHook}`);\n  }\n\n  const threadId = `tmux-test-${Date.now()}`;\n  const turnId = `turn-${Date.now()}`;\n  const message = args.join(' ').trim() || 'tmux-hook test payload';\n  const payload = {\n    type: 'agent-turn-complete',\n    cwd,\n    'thread-id': threadId,\n    'turn-id': turnId,\n    'input-messages': ['omx tmux-hook test'],\n    'last-assistant-message': message,\n  };\n\n  const result = spawnSync(process.execPath, [notifyHook, JSON.stringify(payload)], {\n    cwd,\n    encoding: 'utf-8',\n      windowsHide: true,","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/tmux-hook.ts#L435-L471","documentation":"The tmux-hook test subcommand needs the compiled notify-hook.js script under <package-root>/dist/scripts/ to spawn. This error means that file is missing, almost always because the package was installed from raw source without running the build step, or a publish/pack step omitted dist/.","triggerScenarios":"Running `omx tmux-hook test ...` when dist/scripts/notify-hook.js does not exist relative to getPackageRoot() — e.g. cloned repo without `npm run build`, partially installed package, or dist/ cleaned by a clean script.","commonSituations":"Developing from a git clone; CI cache pruned dist/; installing with package managers that strip build artifacts; version upgrades where build output layout changed.","solutions":["Run the package build (`npm run build` / `npm run prepare`) to regenerate dist/scripts/notify-hook.js, then retry","If installed from npm, reinstall the package (`npm install <pkg> --force`) — published builds should ship dist","Verify getPackageRoot() resolves to the expected directory (no symlink weirdness) and that dist/scripts exists"],"exampleFix":"# before\nomx tmux-hook test hello\n# Error: notify-hook.js not found at /app/node_modules/omx/dist/scripts/notify-hook.js\n\n# after\ncd /app/node_modules/omx && npm run build\nomx tmux-hook test hello","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nconst hook = join(pkgRoot, 'dist', 'scripts', 'notify-hook.js');\nif (!existsSync(hook)) {\n  console.error('dist not built — run npm run build in the package before tmux-hook test');\n  process.exit(2);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run the package build step after cloning or updating","In CI, add a step asserting dist/scripts/notify-hook.js exists before tests","Prefer npm-published builds which bundle dist"],"tags":["cli","build-artifacts","tmux","missing-file"],"backgroundTag":"missing-build-artifact","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}