# Reject unknown struct keys with struct!/2

Use `struct!/2` when runtime attributes must contain only fields that belong to the struct.

```elixir
defmodule Profile do
  @enforce_keys [:name]
  defstruct [:name, role: :member]
end

attrs = [name: "Ada", roel: :admin]

struct(Profile, attrs)
# => %Profile{name: "Ada", role: :member}

struct!(Profile, attrs)
# ** (KeyError) key :roel not found
```

`struct/2` silently ignores keys the struct does not know. That can be useful when deliberately taking a compatible subset, but it can also turn a typo such as `:roel` into a successful-looking value that kept the default `:role`.

`struct!/2` emulates struct literal checks at runtime. It rejects unknown fields, and when its first argument is a module, it also enforces fields declared with `@enforce_keys`. When its first argument is an existing struct, it validates keys like `%Profile{profile | role: :admin}` does.

String keys are invalid too. Do not solve that by calling `String.to_atom/1` on external input. Convert only an explicit allowlist of accepted fields, then pass the result to `struct!/2`.

[Kernel.struct!/2 docs](https://hexdocs.pm/elixir/Kernel.html#struct!/2)


---

Created by: almirsarajcic
Date: September 02, 2026
URL: https://elixirdrops.net/d/1QBcMjiG
