Understanding witr Exit Codes for Scripting and CI Integration

witr returns distinct exit codes (0–6) defined in internal/app/app.go that let scripts distinguish between success, invalid input, permission errors, missing targets, unsupported platforms, and internal failures.

The pranshuparmar/witr repository provides a command-line utility for inspecting system resources such as processes, sockets, and containers. When integrating witr into automation pipelines or shell scripts, understanding its witr exit codes is essential for robust error handling. These numeric constants allow CI systems and scripts to react appropriately to different failure modes without parsing stderr messages.

Exit Code Reference

In internal/app/app.go, the withExitCode helper (defined around line 121) maps each error scenario to a specific integer. The main entry point subsequently passes this value to os.Exit. The following table lists the constants, their numeric values, and semantic meanings.

Code Constant Meaning
0 ExitSuccess Normal termination. The requested operation completed successfully.
1 ExitError Generic error. An unspecified failure occurred during execution.
2 ExitInvalidInput Invalid input. Command-line arguments were malformed or mutually exclusive (e.g., missing required flags like --pid, --port, or --container).
3 ExitPermission Permission denied. The operation required elevated privileges that the current user does not possess.
4 ExitTargetNotFound Target not found. The specified resource (process, file, socket, container, etc.) could not be located.
5 ExitUnsupported Unsupported platform. The requested feature is not available on the current operating system.
6 ExitInternal Internal error. An unexpected state or panic occurred inside witr, indicating a potential bug.

These values are verified by unit tests in internal/app/exitcode_test.go, ensuring the contract remains stable across releases.

How Exit Codes Are Generated

The exit code flow follows three specific steps in the source.

First, when an error condition is detected, the withExitCode function attaches a numeric constant to the error object. This occurs at line 121 of internal/app/app.go, where a switch statement assigns the appropriate code based on the error type.

Second, the main() function in cmd/witr/main.go invokes errExitCode(err) to extract the integer from the error. This helper returns the embedded code or defaults to ExitError (1) if no code was attached.

Finally, the program terminates by calling os.Exit(errExitCode(err)) around line 243 of the main application logic, passing the numeric value to the operating system.

Scripting and CI Integration Examples

The following patterns demonstrate how to consume these exit codes in real-world automation.

Retry Logic in Bash

Use code 4 (ExitTargetNotFound) to implement transient-failure retries.

#!/usr/bin/env bash
MAX_ATTEMPTS=3
attempt=1

while (( attempt <= MAX_ATTEMPTS )); do
    witr --pid 1234 && break
    rc=$?
    if (( rc == 4 )); then
        echo "Target not ready, retry $attempt/$MAX_ATTEMPTS..."
        ((attempt++))
        sleep 2
        continue
    fi
    echo "witr failed with exit code $rc"
    exit $rc
done

PowerShell Error Handling

Distinguish permission issues from other failures using $LASTEXITCODE.

witr --port 8080
$rc = $LASTEXITCODE

switch ($rc) {
    0 { Write-Host "Success." }
    3 { Write-Warning "Permission denied – try running as Administrator." }
    default { Write-Error "witr exited with code $rc" ; exit $rc }
}

GitHub Actions Workflow

Fail CI steps explicitly based on specific error conditions.

steps:
  - name: Check process status
    run: witr --pid ${{ env.PROCESS_ID }}
    env:
      PROCESS_ID: 4321
  - name: Handle specific failures
    if: failure()
    run: |
      echo "witr returned exit code ${{ steps.check_process_status.exitcode }}"
      exit ${{ steps.check_process_status.exitcode }}

Summary

  • witr defines seven exit codes (0–6) as constants in internal/app/app.go, covering success, generic errors, invalid input, permissions, missing targets, unsupported platforms, and internal bugs.
  • The withExitCode helper at line 121 maps errors to integers, while os.Exit(errExitCode(err)) around line 243 terminates the process with the correct status.
  • Scripts can check $? (Bash) or $LASTEXITCODE (PowerShell) to implement conditional logic such as retries on code 4 or privilege escalation on code 3.
  • CI pipelines benefit from deterministic failure modes that do not require parsing text output.

Frequently Asked Questions

What exit code does witr return when a target process is not found?

witr returns code 4 (ExitTargetNotFound). This allows scripts to distinguish between a missing resource and other failure types without inspecting error strings.

How can I check witr exit codes in a shell script?

In Bash, capture $? immediately after the command. In PowerShell, use $LASTEXITCODE. Both variables hold the numeric value passed to os.Exit by the witr runtime.

Where are the exit code constants defined in the witr source?

The constants are defined in internal/app/app.go within the withExitCode function starting at line 121. Unit tests validating these values reside in internal/app/exitcode_test.go.

Does witr return different exit codes on Windows versus Linux?

No. witr unifies platform-specific failures into the same numeric codes. For example, an unsupported feature returns code 5 (ExitUnsupported) regardless of whether the host runs Windows, Linux, or macOS, ensuring cross-platform scripts behave consistently.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →