Hive Hive
Sign in

fix(mcp): keep changeset errors from crashing on non-binary opts

GitHub issue · Closed

Metadata
Source
tuist/hive #25
Updated
Jun 24, 2026
Domains
Hive
Details

Summary

  • Hive.MCP.Tool.changeset_errors/1 interpolates error options into the message via String.replace(msg, "%{key}", to_string(value)). String.replace/3 evaluates its third arg eagerly, so to_string/1 is called on every opt regardless of whether its placeholder appears in the message.
  • Ecto.Enum cast errors include type: {:parameterized, {Ecto.Enum, %{...}}} in their opts. Tuples don’t implement String.Chars, so the eager to_string/1 raises Protocol.UndefinedError, which surfaces to the MCP transport as a generic 500. Reproducer: call update_spec with a status value not in the enum (e.g. "accepted" against the current [:draft, :proposed, :approved, :paused, :rejected, :in_progress, :shipped, :archived]).
  • Switch to the function form of String.replace/3 so options are only stringified when the placeholder is actually present. Add a stringify_option/1 helper that handles strings, atoms, and numbers cleanly, and falls back to inspect/1 for any other shape so future Ecto error opts can’t regress this.

Test plan

  • mix test test/hive/mcp/tool_test.exs — new test casts a bogus value into a parameterized Ecto.Enum; previously crashed inside traverse_errors with Protocol.UndefinedError, now returns %{status: ["is invalid"]}.
  • mix test — full suite (306 tests, 0 failures).
  • mix compile --warnings-as-errors, mix format, mix credo --strict on the touched files.

🤖 Generated with Claude Code

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments

No GitHub comments yet.