Hive
fix(mcp): keep changeset errors from crashing on non-binary opts
GitHub issue · Closed
Source
tuist/hive #25
Updated
Jun 24, 2026
Domains
Hive
Summary
Hive.MCP.Tool.changeset_errors/1interpolates error options into the message viaString.replace(msg, "%{key}", to_string(value)).String.replace/3evaluates its third arg eagerly, soto_string/1is 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 implementString.Chars, so the eagerto_string/1raisesProtocol.UndefinedError, which surfaces to the MCP transport as a generic 500. Reproducer: callupdate_specwith astatusvalue 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/3so options are only stringified when the placeholder is actually present. Add astringify_option/1helper that handles strings, atoms, and numbers cleanly, and falls back toinspect/1for 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 parameterizedEcto.Enum; previously crashed insidetraverse_errorswithProtocol.UndefinedError, now returns%{status: ["is invalid"]}. -
mix test— full suite (306 tests, 0 failures). -
mix compile --warnings-as-errors,mix format,mix credo --stricton the touched files.
🤖 Generated with Claude Code
No GitHub comments yet.