{
  "id": 20095467,
  "title": "Exit codes in CI: what every number means and how to fix it",
  "url": "https://urgent.news/2026/11/15/exit-codes-in-ci-what-every-number-means-and-how-to-fix-it",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-11-15T01:50:47.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/kalemi/exit-codes-in-ci-what-every-number-means-and-how-to-fix-it-3fgb"
  },
  "original_language": "en",
  "account": "Exit codes in CI pipelines convey essential information about the success or failure of individual steps within a continuous integration process. This article explains what each exit code typically signifies, the common causes behind them when running on a Latchkey latchkey-small runner, and recommended actions to resolve the issues.\n\nWhen a command exits with a value between 0 and 255, 0 indicates successful completion. Any other value is convention-based and overlaps across different shells and tools. Bash reserves two codes for its own use: 127 signifies a missing or non-executable command, while 126 is returned when a command is found but not executable. All other values (0 to 125) are determined by the program itself, with each program using them differently.\n\nGitHub Actions does not add its own exit codes; instead, it replicates what the shell reported, ensuring consistency across different environments. The three main factors that determine the exit code are the program, the shell, or a signal.\n\n1. Program-specific exit codes: Programs like curl, apt-get, and pytest each have their own set of exit codes. For example, curl generates codes such as 28 (operation timed out), 100 (HTTP error), and 5 (pytest failure). Apt-get's only failure code is 100, indicating an error in locating a package. pytest defines six distinct exit codes.\n\n2. Shell-specific exit codes: The shell can also influence the exit code, returning 126 or 127 depending on whether the command was found or executable. Additionally, a signal can choose the exit code, represented as 128 plus the signal number. This signifies that the process was terminated by an external signal rather than a program's decision.\n\nTo troubleshoot exit codes, it is essential to first identify the family of the code (program, shell, or signal) and then investigate the specific cause within that family. For program-specific codes, reading the relevant documentation or error messages can provide valuable insights. Shell-related codes often require examining the command's invocation, fixing any syntax errors, or adjusting configuration settings. Signal-related exit codes typically point to system-level issues, such as out-of-memory conditions or signal handling problems.",
  "summary": "Exit codes in CI are the only thing a failed step gets to say about itself, which is why so much of debugging a pipeline comes down to reading one number. This page is the table: what each code means, what usually produced it on a GitHub Actions runner, the fix, and the code a real latchkey-small runner reported for every row in it. The same field in the Actions log carries all three. Which…",
  "key_points": [
    "Exit codes indicate success (0) or failure in CI pipelines",
    "0 means successful completion, others are convention-based",
    "Bash reserves 127 (missing command) and 126 (executable issue)"
  ],
  "editors_take": "Mastering the distinction between program, shell, and signal codes allows developers to transform cryptic pipeline failures into actionable troubleshooting steps for more stable continuous integration workflows.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}