> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trytalkvalue.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exit codes

> Stable exit codes for every TalkValue CLI command. Branch on success, auth failure, not found, and more.

The TalkValue CLI returns a predictable exit code on every run so shell scripts and CI pipelines can branch on outcome without parsing output. Pair the code with the JSON error envelope on stderr to surface a useful message.

## Reference

| Code | Meaning              | When you see it                                                                  |
| ---- | -------------------- | -------------------------------------------------------------------------------- |
| `0`  | Success              | The command completed and printed its result.                                    |
| `1`  | General error        | Unexpected failure. Network error or transient API issue.                        |
| `2`  | Usage error          | Bad arguments, unknown option, missing required value.                           |
| `3`  | Authentication error | No credentials, invalid or expired token, organization access revoked.           |
| `4`  | Not found            | The targeted resource (person, event, channel, company, tag) doesn't exist.      |
| `5`  | Forbidden            | Authenticated, but the active organization isn't allowed to act on the resource. |

## Read the exit code

```bash theme={null}
talkvalue path person get 999999
echo $?
# 4 = not found
```

## Branch in a shell script

```bash theme={null}
#!/usr/bin/env bash
set -e

if ! result=$(talkvalue path person get "$1" --json 2>&1); then
  case $? in
    3) echo "Authentication failed. Run 'talkvalue auth login'." >&2 ;;
    4) echo "Person $1 not found." >&2 ;;
    5) echo "Not allowed to read person $1 in this organization." >&2 ;;
    *) echo "Lookup failed: $result" >&2 ;;
  esac
  exit 1
fi

echo "$result" | jq '.data.email'
```

`set -e` halts on the first non-zero exit. The `case` block maps each domain code to a human-readable message and re-exits with `1` so the calling script can detect the failure.

## Combine with the JSON error envelope

When `--json` is set (or output is piped), errors land on **stderr** as:

```json theme={null}
{ "error": { "message": "Person 999999 not found" } }
```

Capture it separately from stdout to get both the message and the code:

```bash theme={null}
err=$(talkvalue path person get 999999 --json 2>&1 1>/dev/null)
code=$?
echo "exit=$code"
echo "$err" | jq -r '.error.message'
```

## CI pipelines

Most CI runners (GitHub Actions, GitLab CI, CircleCI) fail a step on any non-zero exit code, so the CLI integrates without extra plumbing:

```yaml theme={null}
- name: Export attendees nightly
  env:
    TALKVALUE_TOKEN: ${{ secrets.TALKVALUE_TOKEN }}
  run: |
    talkvalue path event person export 16 > attendees.csv
```

If `auth login` was skipped because `TALKVALUE_TOKEN` is missing, the command exits `3` and the CI step fails with the auth error printed to stderr.

## Related

* [Output format](/cli/output-format). Error envelope shape on stderr.
* [Authentication](/cli/authentication). What causes a `3` and how to fix it.
* [Troubleshooting](/cli/troubleshooting). Common failure modes by exit code.
