-
-
Notifications
You must be signed in to change notification settings - Fork 0
Error Handling
Eshan Roy edited this page Jun 16, 2026
·
3 revisions
M31 Autonomous (M31A) uses a structured error system with sentinel errors and user-friendly messages.
Source: internal/errors/errors.go
| Error | Description | User Message |
|---|---|---|
ErrProviderUnreachable |
Provider cannot be reached | "Check your internet connection" |
ErrProviderNotFound |
Unknown provider name | "Use /settings to configure providers" |
ErrInvalidProvider |
Empty provider name | "Invalid provider name" |
ErrRateLimited |
HTTP 429 received | "Retry in a moment" |
ErrInvalidKey |
Invalid or missing API key | "Run /settings to update" |
ErrNoCredits |
Account out of credits | "Please top up your account" |
ErrModelNotFound |
Requested model not available | "Use /models to see available models" |
| Error | Description | User Message |
|---|---|---|
ErrSessionCorrupted |
Session data is invalid | "Try resuming from a different session" |
ErrSessionNotFound |
No session at path | "Check the session ID" |
ErrSessionPermission |
Cannot access session | "Check file permissions" |
ErrCheckpointNotFound |
No checkpoint to restore | "No previous state to restore" |
| Error | Description | User Message |
|---|---|---|
ErrToolExecution |
Tool failed to execute | "Check the error details" |
ErrToolInputTooLarge |
Input exceeds size limit | "Reduce the input size" |
ErrPermissionDenied |
Permission denied | "Check file permissions" |
ErrInvalidTimeout |
Invalid timeout value | "Must be between 1 and 30 minutes" |
ErrPrivateIPBlocked |
SSRF protection triggered | "SSRF protection active" |
| Error | Description | User Message |
|---|---|---|
ErrPhaseTransition |
Invalid phase transition | "Current phase does not allow this action" |
ErrTaskFailed |
Task execution failed | "Check the task output for details" |
ErrCircularDependency |
Circular task dependency | "Check task dependencies" |
| Error | Description | User Message |
|---|---|---|
ErrStreamTruncated |
Stream ended before [DONE] | "Stream interrupted -- try again" |
ErrContextExceeded |
Token limit exceeded | "Use /compress to reduce context" |
| Error | Description | User Message |
|---|---|---|
ErrBisectResetFailed |
Git bisect reset failed | "Try git bisect reset manually" |
ErrBisectFailed |
Git bisect operation failed | "Check bisect state and retry" |
ErrGitNotInitialized |
Not in a git repository | "Ensure you're in a git repository" |
UserMessage(error) converts any error into a user-friendly, actionable message. It uses a two-tier strategy:
-
Sentinel matching --
errors.Is()for exact sentinel error comparison - Pattern matching -- String matching on the error text for unwrapped errors
For errors that don't match sentinels, patterns are detected:
| Pattern | Message |
|---|---|
connection refused |
"Cannot reach provider" |
context canceled / context deadline exceeded
|
"Request cancelled" |
eof / unexpected end of json
|
"Connection lost" |
i/o timeout / dial tcp
|
"Connection timed out" |
tls / certificate
|
"TLS error" |
bad request / status 400
|
"Bad request" |
forbidden / status 403
|
"Access forbidden" |
not found / status 404
|
"Resource not found" |
internal server error / status 500
|
"Provider internal error" |
| HTTP 401 pattern | "Invalid API key" |
| HTTP 429 pattern | "Rate limited" |
| HTTP 503 pattern | "Provider temporarily unavailable" |
Errors are wrapped with fmt.Errorf("context: %w", err) throughout the codebase, allowing errors.Is() to match through the chain:
return fmt.Errorf("save checkpoint: %w", err)
return fmt.Errorf("tool %s: %w", call.Name, err)
return fmt.Errorf("bisect start: %w", err)Tool execution errors are returned in two ways:
-
ToolResult.Error-- Soft errors logged in the result (e.g., permission rule errors) - Go error return -- Hard errors that propagate up (e.g., permission denied)
The dispatcher distinguishes these via the toolResultError wrapper type:
type toolResultError struct {
result types.ToolResult
}Provider errors are sanitized before display:
- Capped at
MaxProviderErrorChars(200) characters - HTTP status codes extracted and mapped to user messages
- Internal error details stripped for security