Skip to content

Error Handling

Eshan Roy edited this page Jun 16, 2026 · 3 revisions

Error Handling

M31 Autonomous (M31A) uses a structured error system with sentinel errors and user-friendly messages.

Sentinel Errors

Source: internal/errors/errors.go

Provider Errors

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"

Session Errors

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"

Tool Errors

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"

Workflow Errors

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"

Stream Errors

Error Description User Message
ErrStreamTruncated Stream ended before [DONE] "Stream interrupted -- try again"
ErrContextExceeded Token limit exceeded "Use /compress to reduce context"

Git Errors

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 Function

UserMessage(error) converts any error into a user-friendly, actionable message. It uses a two-tier strategy:

  1. Sentinel matching -- errors.Is() for exact sentinel error comparison
  2. Pattern matching -- String matching on the error text for unwrapped errors

Pattern Matching

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"

Error Wrapping

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 Result Errors

Tool execution errors are returned in two ways:

  1. ToolResult.Error -- Soft errors logged in the result (e.g., permission rule errors)
  2. 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 Error Sanitization

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

Clone this wiki locally