witr Exit Codes Reference: How to Handle Errors in Shell Scripts

witr uses five specific exit codes (0, 1, 2, 3, 4) that let automation scripts distinguish between success, usage mistakes, configuration problems, and runtime failures.

When building automation around the witr container management tool, understanding its exit code behavior is essential for reliable CI/CD pipelines and shell scripts. The pranshuparmar/witr repository implements a clear, predictable exit code system defined in internal/app/exitcode.go and applied consistently through internal/app/app.go.

Complete List of witr Exit Codes

The following table covers every exit code used by witr as implemented in the source code:

Exit code Meaning When returned
0 Success Command completed without errors
1 Generic error Unexpected internal problem (panic, I/O failure)
2 Invalid arguments Malformed flags, unknown sub-commands, or CLI contract violation
3 Configuration error Missing or invalid witr.yaml file
4 Runtime/dependency error Docker, Podman, or other required tools unavailable or failing

These constants are defined in internal/app/exitcode.go and invoked via os.Exit(ece.code) in internal/app/app.go.

How to Check witr Exit Codes in Scripts

Basic Success/Failure Detection

The simplest pattern checks $? immediately after witr invocation:

witr status
if [ $? -eq 0 ]; then
    echo "All containers are healthy"
else
    echo "witr reported an issue"
fi

Granular Error Handling with case Statements

For robust automation, use a case statement to handle specific witr exit codes differently:

witr up
case $? in
    0)  echo "Containers started successfully";;
    2)  echo "Invalid flags – check your command line"; exit 1;;
    4)  echo "Docker/Podman not reachable – retry later"; exit 1;;
    *)  echo "Unexpected error (code $?) – aborting"; exit 1;;
esac

CI Pipeline Retry Logic for Transient Failures

Exit code 4 (runtime error) often indicates temporary conditions worth retrying:

attempt=0
max=3
while [ $attempt -lt $max ]; do
    witr up && break
    rc=$?
    if [ $rc -eq 4 ]; then
        echo "Runtime unavailable, retry #$((attempt+1))"
        attempt=$((attempt+1))
        sleep 5
    else
        echo "Fatal error (code $rc) – aborting"
        exit $rc
    fi
done

Source Code Locations for witr Exit Codes

Understanding where these codes originate helps with debugging and contributions:

Mapping Exit Codes to Script Actions

Scenario Recommended handling
CI/CD success gate Assert $? -eq 0 before proceeding
User input validation Treat code 2 as hard failure (don't retry)
Missing config file Treat code 3 as setup error requiring human intervention
Container runtime offline Retry loop on code 4 with exponential backoff
Unknown failures Log and alert on any unhandled code

Summary

  • witr defines five exit codes (0 through 4) in internal/app/exitcode.go
  • Code 2 signals usage errors that require fixing the command invocation
  • Code 3 indicates witr.yaml configuration problems
  • Code 4 enables retry logic for transient runtime/dependency failures
  • Always check $? immediately after witr commands in scripts, as subsequent commands overwrite the value

Frequently Asked Questions

What exit code does witr return on success?

witr returns 0 on successful completion. This is implemented consistently across all commands and documented in the README.md.

How can I detect if witr failed due to bad command-line arguments?

Check for exit code 2. This specifically indicates invalid arguments or usage errors, as defined in internal/app/exitcode.go and applied in internal/app/app.go.

Should my script retry when witr exits with code 4?

Yes, exit code 4 typically indicates transient runtime or dependency failures (e.g., Docker daemon not yet ready). This is the appropriate candidate for retry logic, unlike code 2 (usage) or code 3 (configuration) which require human intervention.

Where are witr's exit codes defined in the source code?

The numeric constants live in internal/app/exitcode.go, while the actual os.Exit() calls that terminate the process with these codes occur in internal/app/app.go.

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 →