Errors
Error types and exception handling
Overview
All fm.cr errors inherit from Fm::Error, which itself inherits from Exception. This allows you to catch all fm.cr errors with a single rescue clause or handle specific error types individually.
Error Hierarchy
Exception
└── Fm::Error
├── Fm::ModelNotAvailableError
├── Fm::DeviceNotEligibleError
├── Fm::AppleIntelligenceNotEnabledError
├── Fm::ModelNotReadyError
├── Fm::InvalidInputError
├── Fm::GenerationError
│ ├── Fm::ExceededContextWindowSizeError
│ ├── Fm::AssetsUnavailableError
│ ├── Fm::GuardrailViolationError
│ ├── Fm::UnsupportedGuideError
│ ├── Fm::UnsupportedLanguageOrLocaleError
│ ├── Fm::DecodingFailureError
│ ├── Fm::RateLimitedError
│ ├── Fm::ConcurrentRequestsError
│ ├── Fm::RefusalError
│ ├── Fm::InvalidGenerationSchemaError
│ ├── Fm::UnsupportedCapabilityError
│ ├── Fm::UnsupportedTranscriptContentError
│ └── Fm::TranscriptMutationWhileRespondingError
├── Fm::TimeoutError
├── Fm::ToolCallError
└── Fm::InternalError
Error Types
Availability Errors
| Error | Description |
|---|---|
ModelNotAvailableError |
Model is not available for an unspecified reason |
DeviceNotEligibleError |
Device doesn't support Apple Intelligence |
AppleIntelligenceNotEnabledError |
Apple Intelligence is disabled in System Settings |
ModelNotReadyError |
Model is still downloading |
Generation Errors
| Error | Description |
|---|---|
GenerationError |
Generation failed |
ExceededContextWindowSizeError |
Input exceeds the context window |
AssetsUnavailableError |
Required model assets are unavailable |
GuardrailViolationError |
Generation blocked by safety guardrails |
RateLimitedError |
Too many requests in a short time |
ConcurrentRequestsError |
Multiple concurrent requests to the same session |
RefusalError |
Model refused to generate a response |
UnsupportedCapabilityError |
The selected model doesn't support a requested capability (macOS 27+) |
UnsupportedTranscriptContentError |
The transcript contains content the model cannot process (macOS 27+) |
TranscriptMutationWhileRespondingError |
The transcript changed while a response was in progress (macOS 27+) |
Input/Schema Errors
| Error | Description |
|---|---|
InvalidInputError |
Invalid input provided |
UnsupportedGuideError |
Unsupported guide constraint |
UnsupportedLanguageOrLocaleError |
Unsupported language or locale |
DecodingFailureError |
Failed to decode structured output |
InvalidGenerationSchemaError |
Invalid JSON schema for generation |
Tool Errors
| Error | Description |
|---|---|
ToolCallError |
Tool invocation failed |
ToolCallError provides additional context:
| Property | Type | Description |
|---|---|---|
tool_name |
String |
Name of the tool that failed |
arguments_json |
String? |
JSON string of the arguments passed to the tool |
Structured Details
Every Fm::Error has an optional details : JSON::Any? property. When an
error raised by macOS 27 includes associated diagnostic information, fm.cr
preserves it for both blocking and streaming calls. Older SDKs and errors
without associated information return nil.
Common fields also have typed accessors:
| Error | Property | Type |
|---|---|---|
ExceededContextWindowSizeError |
context_size, token_count |
Int64? |
RateLimitedError |
reset_date |
Time? |
UnsupportedGuideError |
schema_name |
String? |
UnsupportedLanguageOrLocaleError |
language_code |
String? |
UnsupportedCapabilityError |
capability |
String? |
UnsupportedTranscriptContentError |
unsupported_content |
Array(JSON::Any)? |
DecodingFailureError |
raw_content, underlying_error_message |
String? |
unsupported_content holds the offending transcript entries encoded the same
way Fm::Transcript#to_json encodes them, so you can inspect which entry the
model rejected instead of reading a stringified description.
The generic details object also contains version, debugDescription, and
stringified FoundationModels metadata when the framework supplies them.
Other Errors
| Error | Description |
|---|---|
TimeoutError |
Operation timed out |
InternalError |
Internal FFI error |
Usage Example
begin
response = session.respond("Hello")
rescue ex : Fm::ExceededContextWindowSizeError
puts "Used #{ex.token_count} of #{ex.context_size} tokens"
rescue ex : Fm::TimeoutError
puts "Timed out: #{ex.message}"
rescue ex : Fm::ToolCallError
puts "Tool '#{ex.tool_name}' failed: #{ex.message}"
puts "Arguments: #{ex.arguments_json}" if ex.arguments_json
rescue ex : Fm::GuardrailViolationError
puts "Blocked by guardrails: #{ex.message}"
rescue ex : Fm::RateLimitedError
puts "Rate limited, try again later"
rescue ex : Fm::Error
puts "fm.cr error: #{ex.message}"
end
Error Codes
Errors are mapped from Swift error codes returned by the FFI layer. The mapping is handled internally by Fm.error_from_swift.