Errors And Config Reference

Copy Markdown View Source

Jidoka funnels every runtime-facing error through Jidoka.Error (a Splode front end) and reads every default through Jidoka.Config. This reference guide documents the error classes, the canonical helpers, and the full defaults table. Use it when wiring telemetry, building app-facing error formatters, or tuning application config.

When To Use This

  • Use this guide when you need to know the exact shape and category of a Jidoka error in logs, telemetry, or HTTP responses.
  • Use this guide when you are configuring Jidoka defaults under :jidoka in your application config.
  • Do not use this guide as a general onboarding doc; see Getting Started.

Prerequisites

  • You can compile and run the :jidoka test suite.
  • You have basic familiarity with the Splode error library.

Quick Example

Normalizing an arbitrary failure and turning it into wire data is two calls.

case Jidoka.turn(MyApp.TimeAgent, "Hello") do
  {:ok, result} ->
    result

  {:error, reason} ->
    error = Jidoka.normalize_error(reason, phase: :turn)
    Jidoka.format_error(error)
    #=> "Jidoka execution failed."

    Jidoka.error_to_map(error)
    #=> %{category: :execution, message: "Jidoka execution failed.", phase: :turn, details: %{...}}
end

The same helpers are exported as Jidoka.Error.normalize/2, Jidoka.Error.format/1, and Jidoka.Error.to_map/1 for direct use inside the package.

Concepts

╭──────────────╮     ╭─────────────────╮     ╭────────────────╮
│ raw reason   │────▶│ Jidoka.Error    │────▶│ Splode error   │
│ (atom, map,  │     │ .normalize/2    │     │ class struct   │
│  exception)  │     ╰─────────────────╯     ╰────────┬───────╯
╰──────────────╯                                      │
                                                      ▼
                                            ╭──────────────────╮
                                            │ Error.format/1   │
                                            │ Error.to_map/1   │
                                            ╰──────────────────╯

Splode error classes are buckets that group together specific error structs. Every public Jidoka API returns either an :ok tuple or one of the four classes.

Fields

Error Classes

ClassModuleSplode classPurpose
Invalid input / validationJidoka.Error.Invalid:invalidCallers passed bad data (missing input, invalid context, unsupported version).
ExecutionJidoka.Error.Execution:executionRuntime-side failure (timeout, exceeded turns, capability returned {:error, _}).
ConfigurationJidoka.Error.Config:configApp-level misconfiguration (missing module, invalid schema).
Internalinternal error wrapper:internalUnknown or unexpected failures wrapped as an internal unknown error.

Each class is a Splode error class with an errors: list of one or more concrete error structs (ValidationError, ConfigError, ExecutionError, or Internal.UnknownError).

Error Structs

StructFieldsUsed for
Jidoka.Error.ValidationError:message, :field, :value, :detailsInvalid inputs (missing input, bad context, unknown agent).
Jidoka.Error.ConfigError:message, :field, :value, :detailsConfig issues (missing agent module, invalid handler arity).
Jidoka.Error.ExecutionError:message, :phase, :detailsRuntime failures (turn timeout, exceeded turns, capability errors).
internal unknown error:message, :details, :errorCatch-all for unexpected terms.

Jidoka.Error.validation_error/2, config_error/2, and execution_error/2 are the canonical constructors. They take a message and either a keyword list or map of details; the :details map is sanitized before any rendering.

Public Helpers

The four most important error helpers, exported from both Jidoka.Error and the top-level Jidoka facade:

HelperReturnsUse
Jidoka.normalize_error/2exceptionTurn any reason (atom, tuple, struct) into a Jidoka/Splode exception.
Jidoka.format_error/1stringShort, human-readable summary suitable for logs or UI.
Jidoka.error_to_map/1mapJSON-friendly map with :category, :message, and structured details.
Jidoka.Error.category/1:validation | :configuration | :execution | :internal | :unknownClassify an already-normalized error.

The format/1 and to_map/1 helpers automatically redact secret-like fields (api_key, authorization, password, secret, token) and omit high-cardinality fields (messages, prompt, request_body, etc.).

Jidoka.Config Defaults

Jidoka.Config reads every default through Application.get_env(:jidoka, key, fallback) and validates the value before returning.

HelperConfig key (under :jidoka)FallbackValidator
Jidoka.Config.default_model/0:default_model"openai:gpt-4o-mini"normalize_model_spec!/2 (ReqLLM input).
Jidoka.Config.default_generation/0:default_generation%{params: %{temperature: 0.0, max_tokens: 500}}normalize_generation!/2.
Jidoka.Config.default_max_model_turns/0:default_max_model_turns8normalize_positive_integer!/2.
Jidoka.Config.default_turn_timeout_ms/0:default_turn_timeout_ms30_000normalize_positive_integer!/2.

Example application configuration:

# config/config.exs
import Config

config :jidoka,
  default_model: "anthropic:claude-3-5-sonnet-latest",
  default_generation: %{params: %{temperature: 0.2, max_tokens: 1_024}},
  default_max_model_turns: 6,
  default_turn_timeout_ms: 45_000

Two additional Jidoka.Config helpers are worth knowing:

HelperPurpose
Jidoka.Config.normalize_model_spec/2Validate any ReqLLM-supported model input without raising.
Jidoka.Config.model_ref/1Render an %LLMDB.Model{} (or any input) back to a "provider:id" string for prompts, logs, and tests.

Common Patterns

  • Always normalize before logging. Raw atoms or tuples lose context; Jidoka.normalize_error/2 adds a category, message, and phase.
  • Use error_to_map/1 at the wire boundary. It is JSON-safe and applies secret redaction automatically.
  • Set defaults in config, not in agents. spec overrides win, but :jidoka defaults are what unify behavior across modules.
  • Treat :invalid as a 4xx and :execution as a 5xx. Mapping Jidoka.Error.category/1 directly to HTTP status codes works well in practice.

Testing

Error tests are most useful when they assert on both the category and the relevant detail.

test "missing input becomes a validation error" do
  error = Jidoka.normalize_error(:missing_input)

  assert Jidoka.Error.category(error) == :validation
  assert %{category: :validation, message: message} = Jidoka.error_to_map(error)
  assert message =~ "input is required"
end

test "config defaults round-trip" do
  Application.put_env(:jidoka, :default_max_model_turns, 12)
  assert Jidoka.Config.default_max_model_turns() == 12
after
  Application.delete_env(:jidoka, :default_max_model_turns)
end

Troubleshooting

SymptomLikely CauseFix
ArgumentError: invalid default_model: ... at boot:jidoka, :default_model is not a valid ReqLLM input.Use a "provider:id" string or a %LLMDB.Model{} struct.
Error map shows category: :unknownThe reason was never normalized.Pipe through Jidoka.normalize_error/2 first.
Logs leak API keys or large promptsDirect inspect/1 on the raw error.Use Jidoka.format_error/1 or Jidoka.error_to_map/1; both sanitize.
{:error, {:turn_timeout_exceeded, _, _}} rendered as a generic messageHelper not used.Jidoka.normalize_error/2 adds phase: :turn and structured details.
New error reason renders as Jidoka execution failed.No dedicated normalizer matched.That is the default Execution fallback; either add a specific normalizer or include the cause via the context argument.

Reference