Context
Commit cb2ba4d ("Make clear the distinction of emptiness between cast and validate_required") changed validate_required/3 to treat empty lists ([]) and empty maps (%{}) as invalid values, alongside nil and empty strings.
Previously:
If the value of a field is nil or a string made only of whitespace, the changeset is marked as invalid
Now:
If the value of a field is nil or an empty string/array/map, the changeset is marked as invalid
This is listed as an Enhancement in the changelog ("Consider empty lists as empty values by default"), but it silently breaks existing code that relies on validate_required accepting [] or %{} as valid values.
Impact
This affects both application code and third-party libraries. For example:
Oban (v2.17 through v2.20.3) has validate_required([:args]) on its Job schema, where args is a map. Jobs created with %{} args (a common and documented pattern) will fail validation:
# This is documented in Oban and widely used
%{} |> MyWorker.new() |> Oban.insert()
# => {:error, #Ecto.Changeset<errors: [args: {"can't be blank", [validation: :required]}]>}
Application schemas with array or map fields that have [] or %{} as valid (and often default) values will also break:
schema "documents" do
field :tags, {:array, :string} # default: []
end
def changeset(doc, attrs) do
doc
|> cast(attrs, [:tags])
|> validate_required([:tags]) # now rejects [] as blank
end
Suggestion
This behavior change should either:
- Be listed as a breaking change with a clear migration path, or
- Be made opt-in rather than changing the default behavior
The previous behavior (only nil and whitespace strings are considered blank) is a reasonable default that many libraries and applications depend on.
Context
Commit cb2ba4d ("Make clear the distinction of emptiness between cast and validate_required") changed
validate_required/3to treat empty lists ([]) and empty maps (%{}) as invalid values, alongsideniland empty strings.Previously:
Now:
This is listed as an Enhancement in the changelog ("Consider empty lists as empty values by default"), but it silently breaks existing code that relies on
validate_requiredaccepting[]or%{}as valid values.Impact
This affects both application code and third-party libraries. For example:
Oban (v2.17 through v2.20.3) has
validate_required([:args])on its Job schema, whereargsis a map. Jobs created with%{}args (a common and documented pattern) will fail validation:Application schemas with array or map fields that have
[]or%{}as valid (and often default) values will also break:Suggestion
This behavior change should either:
The previous behavior (only
niland whitespace strings are considered blank) is a reasonable default that many libraries and applications depend on.