murliv1.0.2
{ } github
§ 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

CodeGo constantMeaningRecoverable
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