<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ci why</title>
    <description>The latest articles on DEV Community by ci why (@ciwhy-tool).</description>
    <link>https://dev.to/ciwhy-tool</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3906067%2F1a961b9b-a057-4e37-b811-e5b8605bef9e.png</url>
      <title>DEV Community: ci why</title>
      <link>https://dev.to/ciwhy-tool</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ciwhy-tool"/>
    <language>en</language>
    <item>
      <title>Why does my CI keep failing? (and how to stop guessing)</title>
      <dc:creator>ci why</dc:creator>
      <pubDate>Thu, 30 Apr 2026 13:08:14 +0000</pubDate>
      <link>https://dev.to/ciwhy-tool/why-does-my-ci-keep-failing-and-how-to-stop-guessing-8jc</link>
      <guid>https://dev.to/ciwhy-tool/why-does-my-ci-keep-failing-and-how-to-stop-guessing-8jc</guid>
      <description>&lt;p&gt;Every developer knows this moment.&lt;/p&gt;

&lt;p&gt;You push a commit. CI runs. It fails. You open the log and stare at 400 lines of output trying to find the one line that actually matters.&lt;/p&gt;

&lt;p&gt;Ten minutes later you're still scrolling.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why CI logs are so hard to read
&lt;/h2&gt;

&lt;p&gt;CI runners don't write logs for humans. They write them for machines. Everything gets dumped — timestamps, progress bars, ANSI escape codes, dependency install output, test runner boilerplate — and somewhere buried in all of it is the actual error.&lt;/p&gt;

&lt;p&gt;The problem isn't that CI is broken. The problem is that the signal is buried under noise.&lt;/p&gt;




&lt;h2&gt;
  
  
  The most common reasons CI fails
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. A test is failing&lt;/strong&gt;&lt;br&gt;
Someone changed code that broke an existing test, or a mock is returning the wrong value. The error is in there — you just have to find it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A dependency version conflict&lt;/strong&gt;&lt;br&gt;
Your CI runner is on a different version of Node, Python, or another runtime than your local machine. Works on your laptop, fails in CI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. An environment variable is missing&lt;/strong&gt;&lt;br&gt;
A secret or config value exists in your local &lt;code&gt;.env&lt;/code&gt; but wasn't added to your CI secrets. The app crashes on startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. A timeout&lt;/strong&gt;&lt;br&gt;
A test or build step is taking too long and CI kills it. The log just says "Process killed" with no explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. A flaky test&lt;/strong&gt;&lt;br&gt;
A test that passes 95% of the time but fails randomly due to timing, network, or order-of-execution issues.&lt;/p&gt;


&lt;h2&gt;
  
  
  The slow way vs the fast way
&lt;/h2&gt;

&lt;p&gt;The slow way is what most developers do — scroll the raw log, Ctrl+F for "error", guess what went wrong, push a fix, wait for CI to run again, repeat.&lt;/p&gt;

&lt;p&gt;The fast way is to pipe your log through &lt;strong&gt;ci-why&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;build.log | ci-why
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It strips all the noise, sends the relevant parts to Claude, and prints back a plain English explanation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;──────────────────────────────────────────────────
  WHY
  The authentication service returns null for the token field
  instead of a valid string, causing the test assertion to fail.

  FAILING LINE
  src/services/auth.test.ts:63

  SUGGESTED FIX
  Check authService.login() in auth.ts — it's returning
  {"token": null} for valid credentials.
──────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of reading 300 lines, you read 8.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to set it up
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ci-why
ci-why setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup wizard walks you through getting a free Anthropic API key and saves it automatically. Takes about 2 minutes.&lt;/p&gt;

&lt;p&gt;Then any time a build fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pipe directly&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;build.log | ci-why

&lt;span class="c"&gt;# Or point at a file&lt;/span&gt;
ci-why ./logs/build.log

&lt;span class="c"&gt;# Get JSON output for scripting&lt;/span&gt;
ci-why &lt;span class="nt"&gt;--json&lt;/span&gt; ./build.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works with Jest, pytest, Go test, Rust/Cargo, and Maven — auto-detected from your log.&lt;/p&gt;




&lt;h2&gt;
  
  
  Works in GitHub Actions too
&lt;/h2&gt;

&lt;p&gt;Add it to your workflow and it automatically posts a plain English explanation as a PR comment every time a build fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Explain failure with ci-why&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.build.outcome == 'failure'&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ciwhy-tool/ci-why@v0.2.0&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;log-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp/build.log&lt;/span&gt;
    &lt;span class="na"&gt;anthropic-api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
    &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;pr-number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.number }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every developer on your team sees the explanation — not just the one who installed the tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  Free and open source
&lt;/h2&gt;

&lt;p&gt;ci-why is completely free. You bring your own Anthropic API key (free to get, costs fractions of a cent per run).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ci-why
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/ciwhy-tool/ci-why" rel="noopener noreferrer"&gt;github.com/ciwhy-tool/ci-why&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: devops, node, testing, productivity, opensource&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>node</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I built a CLI that reads your broken CI log and tells you why it failed in plain English</title>
      <dc:creator>ci why</dc:creator>
      <pubDate>Thu, 30 Apr 2026 12:05:06 +0000</pubDate>
      <link>https://dev.to/ciwhy-tool/i-built-a-cli-that-reads-your-broken-ci-log-and-tells-you-why-it-failed-in-plain-english-3bkd</link>
      <guid>https://dev.to/ciwhy-tool/i-built-a-cli-that-reads-your-broken-ci-log-and-tells-you-why-it-failed-in-plain-english-3bkd</guid>
      <description>&lt;p&gt;Every developer knows the feeling.&lt;/p&gt;

&lt;p&gt;Your CI pipeline fails. You open the log. There are 300 lines of noise — progress bars, timestamps, test runner output — and somewhere buried in there is the one line that actually matters.&lt;/p&gt;

&lt;p&gt;I got tired of hunting for it. So I built &lt;strong&gt;ci-why&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;You pipe your failed CI log into it, and it tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WHY&lt;/strong&gt; the build failed (in one sentence)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which exact line&lt;/strong&gt; caused it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to fix&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;build.log | ci-why
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You get back something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;──────────────────────────────────────────────────
  WHY
  The authentication service is returning null for the token field
  instead of a valid token string, causing the test assertion to fail.

  FAILING LINE
  src/services/auth.test.ts:63

  SUGGESTED FIX
  Check authService.login() in auth.ts — it's returning {"token": null}
  for valid credentials. The login logic needs fixing, not the test.
──────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of reading 300 lines, you read 8.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ci-why
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll need an Anthropic API key (free to get at console.anthropic.com). Set it once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-key-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it however fits your workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pipe from anywhere&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;build.log | ci-why

&lt;span class="c"&gt;# Point at a file&lt;/span&gt;
ci-why ./logs/build.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;ci-why does four things under the hood:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Strips the noise&lt;/strong&gt; — removes ANSI escape codes, progress bars, timestamps, and anything else that clutters CI logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finds the signal&lt;/strong&gt; — pulls out lines containing errors, exceptions, and failures, plus the last section of the log&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asks Claude&lt;/strong&gt; — sends the cleaned excerpt to the Anthropic API with a tight prompt asking for: why, where, and how to fix it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prints the result&lt;/strong&gt; — formats it into the clean coloured output you saw above&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The whole thing uses &lt;code&gt;claude-haiku&lt;/code&gt; which is fast and cheap. A typical analysis costs less than a fraction of a cent.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's free and open source
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ci-why is completely free.&lt;/strong&gt; You bring your own Anthropic API key so there's no subscription, no account, no billing through me.&lt;/p&gt;

&lt;p&gt;The code is on GitHub: &lt;a href="https://github.com/ciwhy-tool/ci-why" rel="noopener noreferrer"&gt;github.com/ciwhy-tool/ci-why&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A paid cloud tier with GitHub Actions integration and team features is planned for the future — but the core CLI will always be free and open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's coming next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions integration (auto-comment on PRs with the failure explanation)&lt;/li&gt;
&lt;li&gt;Support for more log formats (pytest, Go test, Cargo, Maven)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--json&lt;/code&gt; flag for piping output into other tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it and let me know what you think
&lt;/h2&gt;

&lt;p&gt;If you try ci-why and hit a bug, have a suggestion, or just want to say it helped — drop a comment below or open an issue on GitHub. This is v0.1 and real feedback from real developers is exactly what I need to make it better.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ci-why
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update: v0.1.2 is out — better error messages, --version and --help flags, and graceful handling of empty logs. npm install -g ci-why to get it.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>cli</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
