# Understanding witr Exit Codes for Scripting and CI Integration

> Learn what witr exit codes mean for scripting and CI integration. Understand success, errors, and failures to streamline your workflows.

- Repository: [Pranshu Parmar/witr](https://github.com/pranshuparmar/witr)
- Tags: deep-dive
- Published: 2026-08-09

---

**witr returns distinct exit codes (0–6) defined in [`internal/app/app.go`](https://github.com/pranshuparmar/witr/blob/main/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`](https://github.com/pranshuparmar/witr/blob/main/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`](https://github.com/pranshuparmar/witr/blob/main/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`](https://github.com/pranshuparmar/witr/blob/main/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`](https://github.com/pranshuparmar/witr/blob/main/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.

```bash
#!/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`.

```powershell
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.

```yaml
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`](https://github.com/pranshuparmar/witr/blob/main/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`](https://github.com/pranshuparmar/witr/blob/main/internal/app/app.go) within the `withExitCode` function starting at line 121. Unit tests validating these values reside in [`internal/app/exitcode_test.go`](https://github.com/pranshuparmar/witr/blob/main/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.