# How to return error for presence of certain keys

**URL:** <https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769>\
**Category:** dry-validation\
**Created:** [May 3, 2019, 5:22pm UTC](https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769 "2019-05-03T17:22:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![JF-Lalonde](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/jf-lalonde/32/373_2.png) [@JF-Lalonde](https://discourse.dry-rb.org/u/JF-Lalonde)\
**Post date:** [May 3, 2019, 5:22pm UTC](https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769/1 "2019-05-03T17:22:51Z")

</div>

I was wondering if anyone else has found a need to validate against the presence of a key in a hash.  
Right now dry-validation has a macro for `required(...)` and `optional(...)`. I think it would be nice to have another macro like `forbidden(...)` (or some other word, like `exclude` or `refute`) that would fail validation if the key given was present in the input hash.

Here’s a use-case:  
I am validating a settings hash. The hash can be updated but some keys are restricted.  
If the input hash contains a restricted key I want to return an error letting the user know that they cannot modify that key.  
Right now the closest I can get is `optional(:key).value(:none?)` but this isn’t the desired behavior because passing `restricted_key: nil` should also be forbidden.

I am going to implement a custom rule, but I was curious to see if there is a cleaner way to validate against the presence of a key.

---

<div class="post-metadata">

**Author:** ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)\
**Post date:** [May 4, 2019, 6:35pm UTC](https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769/2 "2019-05-04T18:35:41Z")

</div>

This is possible with `dry-validation` `1.0.0` (currently available as `RC2` pre-release). Here’s an example:

```ruby
require 'dry/validation'

class SettingsContract < Dry::Validation::Contract
  schema do
    required(:foo).filled(:string)
    required(:bar).filled(:string)

    optional(:restricted)
  end

  rule(:restricted) do
    key.failure("key :restricted cannot be present") if values.key?(:restricted)
  end
end

sc = SettingsContract.new

puts sc.(foo: 'foo', bar: 'bar', restricted: nil).errors.to_h.inspect
# {:restricted=>["key :restricted cannot be present"]}

```

Does this help?

---

<div class="post-metadata">

**Author:** ![JF-Lalonde](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/jf-lalonde/32/373_2.png) [@JF-Lalonde](https://discourse.dry-rb.org/u/JF-Lalonde)\
**Post date:** [May 6, 2019, 1:40pm UTC](https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769/3 "2019-05-06T13:40:31Z")

</div>

Thanks @solnic, looks like it may be time for us to upgrade all of our dry-rb libraries!

---

<div class="post-metadata">

**Author:** ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)\
**Post date:** [May 6, 2019, 7:33pm UTC](https://discourse.dry-rb.org/t/how-to-return-error-for-presence-of-certain-keys/769/4 "2019-05-06T19:33:44Z")

</div>

Ahh yeah it’s a very good moment. `dry-validation` 1.0.0 final should be ready very soon.
