pretty simple one that showed up in cast testing but skipped at some point.
The Value union type uses tag: :type, tag_value: "dynamic" to identify the dynamic subtype. Value.dynamic/1 wraps to %{type: "dynamic", value: %Dynamic{}}, which the tag matcher finds. But a raw %Dynamic{type: Patch} has :type = Patch (a module), not "dynamic", so the union rejects it before ever reaching Dynamic.cast_input.
The fix is a cast_input override in Value that wraps a bare %Dynamic{} into the tagged map format before delegating to the union:
pretty simple one that showed up in cast testing but skipped at some point.
The Value union type uses tag: :type, tag_value: "dynamic" to identify the dynamic subtype. Value.dynamic/1 wraps to %{type: "dynamic", value: %Dynamic{}}, which the tag matcher finds. But a raw %Dynamic{type: Patch} has :type = Patch (a module), not "dynamic", so the union rejects it before ever reaching Dynamic.cast_input.
The fix is a cast_input override in Value that wraps a bare %Dynamic{} into the tagged map format before delegating to the union: