§ API
Exit codes
Exit codes distinguish failure categories. Agents use them to decide whether to retry, escalate, or surface the error to the user. The values are identical across all language implementations.
Code table
| Code | Go constant | Meaning | Recoverable |
|---|---|---|---|
| 0 | ExitOK | Success | — |
| 1 | ExitUserError | Invalid input: bad flags, wrong argument type, constraint violation | Yes — fix input and retry |
| 2 | ExitToolError | Internal failure: dependency error, unexpected state, tool bug | Sometimes — check recoverable field |
| 3 | ExitPartial | Partial success: some operations succeeded, some failed. Check result for details. | Depends on context |
| 4 | ExitTimeout | Operation timed out before completing | Yes — retry after a delay |
| 5 | ExitNotFound | Requested resource does not exist | No — unless the resource is expected to be created |
| 6 | ExitPermission | Insufficient permissions to perform the operation | No — requires permission change |
| 7 | ExitConflict | State conflict: resource already exists, concurrent modification detected | Sometimes — may resolve with a delete first |
| 8 | ExitRateLimited | Rate limit reached. Check retry_after_ms field for wait duration. |
Yes — retry after retry_after_ms |
| 9 | ExitCancelled | Operation was cancelled before completing | Yes — retry if still needed |
In error envelopes
The exit code appears as code in the error envelope written to stderr. The process also exits with this code.
jsonstderr
{
"status": "error",
"code": 5,
"error": "not_found",
"message": "index file does not exist at ~/.mytool/index.db",
"suggestion": "Run `mytool index build` to create the index.",
"recoverable": true,
"schema_version": "1.0",
"tool_version": "1.0.2"
}
ExitFunc override
murli.ExitFunc defaults to os.Exit. Override it in tests to capture the exit code without terminating the process.
goyour_test.go
var capturedCode int
murli.ExitFunc = func(code int) {
capturedCode = code
}
defer func() { murli.ExitFunc = os.Exit }()
// run your command handler
// assert capturedCode == murli.ExitNotFound