# Changeset is not validating data

**URL:** <https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354>\
**Category:** Questions\
**Tags:** ecto, changeset\
**Created:** [April 8, 2025, 10:35am UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354 "2025-04-08T10:35:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fl4m3Ph03n1x](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/32/11709_2.png) [@Fl4m3Ph03n1x](https://forum.elixirforum.com/u/Fl4m3Ph03n1x)\
**Post date:** [April 8, 2025, 10:35am UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/1 "2025-04-08T10:35:53Z")

</div>

## Background

I am trying to create a schema with some basic validations. However, when I spin up my app, it looks like the validations are not running.

## Code

This is the schema for a reservation.

```elixir
defmodule MyApp.Reserve do
  @moduledoc """
  Represents a reservation for a guest.
  """

  use Ecto.Schema

  import Ecto.Query

  alias Ecto.Changeset

  schema "reserves" do
    field :guest_id, Ecto.UUID
    field :reserved, :decimal
    field :paid, :decimal
    field :category, Ecto.Enum, values: [:new, :returning]
  end

  def changeset(reserve, params \\ %{}) do
    reserve
    |> Changeset.cast(params, [:guest_id, :reserved, :paid, :category])
    |> Changeset.validate_required([:guest_id, :reserved, :paid, :category])
    |> Changeset.validate_number(:reserved, greater_than_or_equal_to: 0)
    |> Changeset.validate_number(:paid, greater_than_or_equal_to: 10)
    |> Changeset.validate_inclusion(:category, ["new", "returning"])
  end

end

```

## Iex

```elixir
alias MyApp.Repo
alias MyApp.Reserve

reserve = %Reserve{guest_id: "bcf6dba1-8542-462e-ac16-6cfbe7be4cf6", reserved: 0, paid: -10}

Reserve.changeset(reserve)
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #MyApp.Reserve<>, valid?: true, ...>

```

## Question

This should be `valid?: false` since `paid` is a negative number. What am I missing?

---

<div class="post-metadata">

**Author:** ![michallepicki](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/5f9b8f/32.png) [@michallepicki](https://forum.elixirforum.com/u/michallepicki)\
**Post date:** [April 8, 2025, 10:47am UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/2 "2025-04-08T10:47:06Z")

</div>

The changes will be validated and you may see errors after “applying an action” - it can be e.g. when you call `Repo` to `insert` or `update`, or if you need to you can call `apply_action/2` yourself

edit: also, if you’re making changes to a struct you would pass the changes in the params map - and those would then get casted and get validated

---

<div class="post-metadata">

**Author:** ![LostKobrakai](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/32/3072_2.png) [@LostKobrakai](https://forum.elixirforum.com/u/LostKobrakai)\
**Post date:** [April 8, 2025, 10:52am UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/3 "2025-04-08T10:52:22Z")

</div>

> [@michallepicki](#):
>
> The changes will be validated and you may see errors after “applying an action”

That’s not the issue. Validations run at the time the validation function is called.

> [@Fl4m3Ph03n1x](#):
>
> This should be `valid?: false` since `paid` is a negative number.

Validations generally only validate changes, not the existing data on the `reserve` struct – they’re expected to be valid as supplied. You’re calling the `changeset/2` function with no changes. `validate_required` is the only exception to that for `Ecto.Changeset` supplied validations.

---

<div class="post-metadata">

**Author:** ![dimitarvp](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/32/38664_2.png) [@dimitarvp](https://forum.elixirforum.com/u/dimitarvp)\
**Post date:** [April 8, 2025, 11:48am UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/4 "2025-04-08T11:48:25Z")

</div>

To have `Ecto.Changeset` work as designed you should give it an empty `%Reserve{}` and then pass parameters in the form of a regular map that contain all the pieces of data you want validated. Or a mix.

---

<div class="post-metadata">

**Author:** ![michallepicki](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/5f9b8f/32.png) [@michallepicki](https://forum.elixirforum.com/u/michallepicki)\
**Post date:** [April 8, 2025, 2:25pm UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/5 "2025-04-08T14:25:08Z")

</div>

> [@LostKobrakai](#):
>
> That’s not the issue. Validations run at the time the validation function is called.

oh, right, I got confused because Phoenix is not showing errors when the action is not set

---

<div class="post-metadata">

**Author:** ![garrison](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/32.png) [@garrison](https://forum.elixirforum.com/u/garrison)\
**Post date:** [April 8, 2025, 5:36pm UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/6 "2025-04-08T17:36:00Z")

</div>

Note there are times where it is okay to pass in a struct _with_ fields set, namely when you explicitly _don’t_ want to validate them because they come from your own code. Sometimes I’ll throw in something which is set statically (e.g. `Post{type: :something}`) or a foreign key that way.

---

<div class="post-metadata">

**Author:** ![dimitarvp](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/32/38664_2.png) [@dimitarvp](https://forum.elixirforum.com/u/dimitarvp)\
**Post date:** [April 8, 2025, 6:03pm UTC](https://forum.elixirforum.com/t/changeset-is-not-validating-data/70354/7 "2025-04-08T18:03:22Z")

</div>

Yeah. First parameter to `cast` is data you already trust.
