{"id":15058,"library":"why-broke","title":"why-broke Causal Debugger","description":"why-broke is a command-line utility designed for causal debugging of build failures in JavaScript/TypeScript projects. It tackles the common problem of \"it worked yesterday, but not today\" by detecting subtle environmental and dependency changes that conventional version control systems like Git might miss. The tool operates by taking a \"good state\" snapshot of the system, which includes critical factors like Node.js version, operating system, lockfile hashes, package manifest versions, key configuration files (e.g., `tsconfig`, `webpack`), and essential environment variable keys. When a build subsequently fails, why-broke compares the current \"bad state\" against the last known good state to pinpoint the root cause, such as silent dependency updates, missing environment variables, or unexpected Node.js version discrepancies. As of version 1.4.2, it incorporates a causal inference engine with specialized detectors for runtime, dependencies, configuration, environment, and Git status. The package is actively maintained and appears to follow a typical semantic versioning release cadence based on its version history. Its primary differentiator is its focus on diagnosing *why* a build failed rather than merely *where* it failed, offering actionable fixes.","status":"active","version":"1.4.2","language":"javascript","source_language":"en","source_url":"https://github.com/Adi-gitX/why-this-broke","tags":["javascript","debugging","build-tools","diff","causality","drift-detection","regression","ci","build-failure"],"install":[{"cmd":"npm install why-broke","lang":"bash","label":"npm"},{"cmd":"yarn add why-broke","lang":"bash","label":"yarn"},{"cmd":"pnpm add why-broke","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"why-broke is primarily a CLI tool; direct programmatic imports like this are not officially documented but might be possible if a programmatic API exists. This assumes an 'init' function mirroring the CLI command.","wrong":"const init = require('why-broke').init;","symbol":"init","correct":"import { init } from 'why-broke';"},{"note":"This speculates a named export for the 'record' functionality. CommonJS require for named exports would typically be 'require(\"why-broke\").record'.","wrong":"import record from 'why-broke';","symbol":"record","correct":"import { record } from 'why-broke';"},{"note":"Assumes a named 'check' function. The 'wrong' example attempts a default import or a full module import to a variable named 'check', which would be incorrect for a named export.","wrong":"const check = require('why-broke');","symbol":"check","correct":"import { check } from 'why-broke';"}],"quickstart":{"code":"import { exec } from 'child_process';\nimport path from 'path';\n\n// This script demonstrates common why-broke usages programmatically,\n// often seen in build scripts or advanced CI/CD setups where shell commands\n// are orchestrated via Node.js.\n\nconst projectRoot = process.cwd(); // Assumes script is run from project root\n\nasync function setupAndRunWhyBroke() {\n  console.log('1. Installing why-broke as a dev dependency...');\n  // Ensure why-broke is available. In a real scenario, this might be in package.json.\n  await new Promise<void>((resolve, reject) => {\n    exec('npm install --save-dev why-broke', { cwd: projectRoot }, (err, stdout, stderr) => {\n      if (err) {\n        console.error(`Installation failed: ${stderr}`);\n        return reject(err);\n      }\n      console.log(stdout);\n      resolve();\n    });\n  });\n\n  console.log('\\n2. Initializing why-broke in the project...');\n  // This sets up automatic state recording on 'npm install'\n  await new Promise<void>((resolve, reject) => {\n    exec('npx why-broke init', { cwd: projectRoot }, (err, stdout, stderr) => {\n      if (err) {\n        console.error(`Init failed: ${stderr}`);\n        return reject(err);\n      }\n      console.log(stdout);\n      resolve();\n    });\n  });\n\n  console.log('\\n3. Attempting a wrapped build with why-broke...');\n  // why-broke will record a \"good state\" if this build succeeds,\n  // or diagnose if it fails.\n  await new Promise<void>((resolve, reject) => {\n    exec('npx why-broke \"npm run build\"', { cwd: projectRoot }, (err, stdout, stderr) => {\n      console.log(stdout); // why-broke's diagnostic output will be here\n      if (stderr) {\n        console.error(stderr);\n      }\n      if (err) {\n        console.error(`\\nBuild command failed with exit code ${err.code}.`);\n        console.error('why-broke should have provided a diagnosis above.');\n        return reject(err);\n      }\n      console.log('\\nBuild succeeded. why-broke might have recorded a new good state.');\n      resolve();\n    });\n  });\n\n  console.log('\\nDemonstration complete.');\n}\n\nsetupAndRunWhyBroke().catch(error => {\n  console.error('An error occurred during the why-broke demonstration:', error);\n  process.exit(1);\n});\n","lang":"typescript","description":"This TypeScript example demonstrates installing, initializing, and using `why-broke` to wrap a build command programmatically, typical for CI/CD pipelines or automated development scripts."},"warnings":[{"fix":"Add `.why-broke.json` to your project's `.gitignore` file immediately after initializing `why-broke` to prevent accidental commits.","message":"The `.why-broke.json` snapshot file stores local environmental state and should never be committed to version control. Committing it can lead to confusing or incorrect diagnostics when shared across different machines or environments.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Manually re-record a verified good state by running `npx why-broke record` whenever you are certain the project is building and running correctly.","message":"`why-broke`'s accuracy heavily depends on a reliable \"good state\" baseline. If this baseline is outdated, corrupted, or was recorded during a temporarily broken state, subsequent diagnostic reports may be misleading or inaccurate.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Corroborate findings from the `GitDetector` with manual inspection of `git status` and `git log` for a more certain diagnosis regarding Git-related drift.","message":"The `GitDetector` within `why-broke` provides change reports with `LOW` confidence for aspects like Git history or dirty working directories. These reports are less definitive than `HIGH` confidence reports from other detectors.","severity":"gotcha","affected_versions":">=1.4"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Install `why-broke` globally via `npm install -g why-broke` or as a dev dependency with `npm install --save-dev why-broke`. Ensure `npx` is available and in your system's PATH.","cause":"The `why-broke` package is not installed globally or locally, or `npx` cannot locate it in the current environment's PATH.","error":"command not found: why-broke"},{"fix":"Run `npx why-broke record` when your project is in a verified working condition to establish a fresh, reliable baseline for future comparisons.","cause":"The previously recorded \"good state\" baseline is missing, corrupted, or was set when the project was already in a problematic state, preventing meaningful comparison.","error":"✖ Command failed. Diagnosing cause... (followed by an empty or unhelpful report)"},{"fix":"Ensure the user has write permissions in the project root. Avoid running `npm` or `npx` commands with `sudo` unless absolutely necessary, as this can lead to incorrect file ownership and permissions.","cause":"The user executing `why-broke` does not have sufficient file system write permissions to create or modify the `.why-broke.json` file in the project's root directory.","error":"Error: EACCES: permission denied, open '.why-broke.json'"}],"ecosystem":"npm"}