When trying to set password using my own update I get Postgres type error in AshAuthentication

This boils down to that Postgres can't find the correct type for a parameter. Is that something I can take care of or is it somewhere else? <former gist-link, replaced by many messages below>
11 Replies
Andreas Ekeroot @ work
I just realized that I could split the question into many messages! Here goes! Here's my bespoke action in the User resource:
update :backoffice_set_password do
description "Set the password for a user"

argument :password, :string do
description "The proposed password for the user, in plain text."
allow_nil? false
constraints min_length: 8
sensitive? true
end

argument :password_confirmation, :string do
description "The proposed password for the user (again), in plain text."
allow_nil? false
sensitive? true
end

change set_context(%{strategy_name: :password})
validate AshAuthentication.Strategy.Password.PasswordConfirmationValidation
change AshAuthentication.Strategy.Password.HashPasswordChange
change AshAuthentication.GenerateTokenChange
change atomic_update(:updated_at, expr(now()))
end
update :backoffice_set_password do
description "Set the password for a user"

argument :password, :string do
description "The proposed password for the user, in plain text."
allow_nil? false
constraints min_length: 8
sensitive? true
end

argument :password_confirmation, :string do
description "The proposed password for the user (again), in plain text."
allow_nil? false
sensitive? true
end

change set_context(%{strategy_name: :password})
validate AshAuthentication.Strategy.Password.PasswordConfirmationValidation
change AshAuthentication.Strategy.Password.HashPasswordChange
change AshAuthentication.GenerateTokenChange
change atomic_update(:updated_at, expr(now()))
end
When I run it from the console, like this:
Accounts.get_user_by_id!("f346e870-824a-4494-924f-218da9e35f81", authorize?: false) |> Accounts.backoffice_set_password(%{password: "A super long and excellent password", password_confirmation: "A super long and excellent password"}, authorize?: false)
Accounts.get_user_by_id!("f346e870-824a-4494-924f-218da9e35f81", authorize?: false) |> Accounts.backoffice_set_password(%{password: "A super long and excellent password", password_confirmation: "A super long and excellent password"}, authorize?: false)
I get this error message:
{:error,
%Ash.Error.Unknown{
changeset: "#Changeset<>",
errors: [
%Ash.Error.Unknown.UnknownError{
error: "** (Postgrex.Error) ERROR 42P18 (indeterminate_datatype) could not determine data type of parameter $3\n\n query: UPDATE \"users\" AS u0 SET \"confirmed_at\" = $1::timestamp::timestamp, \"updated_at\" = $2::timestamp::timestamp, \"hashed_password\" = (CASE WHEN $3 IS NULL THEN ash_raise_error($4::jsonb, NULL::text) ELSE $5 END)::text WHERE (u0.\"id\"::uuid = $6::uuid) RETURNING u0.\"id\", u0.\"email\", u0.\"hashed_password\", u0.\"confirmed_at\", u0.\"first_name\", u0.\"last_name\", u0.\"personal_identity_number\", u0.\"phone_number\", u0.\"has_access_to_backoffice\", u0.\"relation\", u0.\"profile_picture\", u0.\"fcm_token\", u0.\"inserted_at\", u0.\"updated_at\", u0.\"family_id\"",
field: nil,
value: nil,
splode: Ash.Error,
bread_crumbs: [],
vars: [],
path: [],
stacktrace: #Splode.Stacktrace<>,
class: :unknown
}
]
}}
{:error,
%Ash.Error.Unknown{
changeset: "#Changeset<>",
errors: [
%Ash.Error.Unknown.UnknownError{
error: "** (Postgrex.Error) ERROR 42P18 (indeterminate_datatype) could not determine data type of parameter $3\n\n query: UPDATE \"users\" AS u0 SET \"confirmed_at\" = $1::timestamp::timestamp, \"updated_at\" = $2::timestamp::timestamp, \"hashed_password\" = (CASE WHEN $3 IS NULL THEN ash_raise_error($4::jsonb, NULL::text) ELSE $5 END)::text WHERE (u0.\"id\"::uuid = $6::uuid) RETURNING u0.\"id\", u0.\"email\", u0.\"hashed_password\", u0.\"confirmed_at\", u0.\"first_name\", u0.\"last_name\", u0.\"personal_identity_number\", u0.\"phone_number\", u0.\"has_access_to_backoffice\", u0.\"relation\", u0.\"profile_picture\", u0.\"fcm_token\", u0.\"inserted_at\", u0.\"updated_at\", u0.\"family_id\"",
field: nil,
value: nil,
splode: Ash.Error,
bread_crumbs: [],
vars: [],
path: [],
stacktrace: #Splode.Stacktrace<>,
class: :unknown
}
]
}}
Here's the actual query:
UPDATE "users" AS u0 SET "confirmed_at" = $1::timestamp::timestamp, "updated_at" = $2::timestamp::timestamp, "hashed_password" = (CASE WHEN $3 IS NULL THEN ash_raise_error($4::jsonb, NULL::text) ELSE $5 END)::text WHERE (u0."id"::uuid = $6::uuid) RETURNING u0."id", u0."email", u0."hashed_password", u0."confirmed_at", u0."first_name", u0."last_name", u0."personal_identity_number", u0."phone_number", u0."has_access_to_backoffice", u0."relation", u0."profile_picture", u0."fcm_token", u0."inserted_at", u0."updated_at", u0."family_id" [~U[2025-09-22 10:14:48.906620Z], ~U[2025-09-22 10:14:48.906550Z], "$2b$12$OGpmqIGQN6GXRvm7f0aCceG3neB7LnrNGJktD12IPMApE2dsqPLai", "{\"input\":{\"type\":\"attribute\",\"resource\":\"Elixir.MyBackend.Accounts.User\",\"field\":\"hashed_password\"},\"exception\":\"Ash.Error.Changes.Required\"}", "$2b$12$WVodIugoyncjaDoXvbV31Os7wO6JaS21QjjqoMY6HgJNyB6P2Dpni", "f346e870-824a-4494-924f-218da9e35f81"]
UPDATE "users" AS u0 SET "confirmed_at" = $1::timestamp::timestamp, "updated_at" = $2::timestamp::timestamp, "hashed_password" = (CASE WHEN $3 IS NULL THEN ash_raise_error($4::jsonb, NULL::text) ELSE $5 END)::text WHERE (u0."id"::uuid = $6::uuid) RETURNING u0."id", u0."email", u0."hashed_password", u0."confirmed_at", u0."first_name", u0."last_name", u0."personal_identity_number", u0."phone_number", u0."has_access_to_backoffice", u0."relation", u0."profile_picture", u0."fcm_token", u0."inserted_at", u0."updated_at", u0."family_id" [~U[2025-09-22 10:14:48.906620Z], ~U[2025-09-22 10:14:48.906550Z], "$2b$12$OGpmqIGQN6GXRvm7f0aCceG3neB7LnrNGJktD12IPMApE2dsqPLai", "{\"input\":{\"type\":\"attribute\",\"resource\":\"Elixir.MyBackend.Accounts.User\",\"field\":\"hashed_password\"},\"exception\":\"Ash.Error.Changes.Required\"}", "$2b$12$WVodIugoyncjaDoXvbV31Os7wO6JaS21QjjqoMY6HgJNyB6P2Dpni", "f346e870-824a-4494-924f-218da9e35f81"]
barnabasj
barnabasj2w ago
Are you on all the latest versions?
Andreas Ekeroot @ work
Maybe... let me check and get back to you! Now I'm running the latest versions of everything, and I'm still getting the same error.
ZachDaniel
ZachDaniel2w ago
...that looks weird Can you create a reproduction?
Andreas Ekeroot @ work
Sure thing! Just new Ash project and put as little code as possible into it to reproduce the error?
ZachDaniel
ZachDaniel2w ago
Yes please 😍 And open an issue
Andreas Ekeroot @ work
Sounds good. I'll do it!
Andreas Ekeroot @ work
GitHub
Trying to update password throws "ERROR 42P18 (indeterminate_dataty...
Code of Conduct I agree to follow this project&#39;s Code of Conduct AI Policy I agree to follow this project&#39;s AI Policy, or I agree that AI was not used while creating this issue. Versions .....
Andreas Ekeroot @ work
I have no idea if this is a good bug report, so I'm happy to get feedback on it.
sevenseacat
sevenseacat2w ago
I just copied that action into my Tunez app (without the atomic_update) and it works 🤔 the SQL I get is a bit different though ooooo no I got the same error (once I made hashed_password non-nullable) so fun question. in @Andreas Ekeroot @ work 's error, why are $3 and $5 in the SQL different values? so its something to do with the action being atomic I think - when adding require_atomic? false its fine - and the HashPasswordChange change
barnabasj
barnabasj2w ago
$3 and $5 are the same I think it's starting with 1 not 0 if it's not done atomically, it does the null check before instead of in the sql I think ah no, they are slightly different that's interesting

Did you find this page helpful?