Validation error prevents publishing when both internal and external link fields are filled

3 replies
Last updated: Apr 13, 2021
Hi, I'm struggling with validation of two fields. My use-case is; I have two fields. Field A is for internal links and field B is for external links. I would like to show an error if both fields are filed out.
My schema is as follows:


{

title: "Artikkel",

name: "article",

type: "reference",

to: [{ type: articleDocument.name }],

description: "Lenke til en artikkel på Löplabbet",

validation: (_Rule_: _any_) =>

_Rule_.custom((_context_: _any_) =>

_context_.article && _context_.url ? true : "Du kan ikke lenke til både artikkel og ekstern URL"

),

},

{

title: "URL",

name: "url",

type: "string",

description: "Lenke til en ekstern side",

validation: (_Rule_: _any_) =>

_Rule_.custom((_context_: _any_) =>

_context_.url && _context_.article ? true : "Du kan ikke lenke til både ekstern URL og artikkel"

),

},

This shows a validation error message if both fields are in use, but I'm not able to publish. And the publish button shows this error: There are validation errors that need to be fixed before this document can be published.
AI Update

I can see the issue in your validation code! The problem is with what you're returning from your rule.custom() function.

Your current validation logic is returning the opposite of what it should:

validation: (Rule: any) =>
  Rule.custom((context: any) =>
    context.article && context.url ? true : "Du kan ikke lenke til både artikkel og ekstern URL"
  ),

This returns true when both fields are filled (which is what you want to prevent), and shows an error when they're not both filled. You need to flip the logic.

Here's the corrected version:

{
  title: "Artikkel",
  name: "article",
  type: "reference",
  to: [{ type: articleDocument.name }],
  description: "Lenke til en artikkel på Löplabbet",
  validation: (Rule) =>
    Rule.custom((value, context) => {
      // Show error if BOTH article and url are filled
      if (context.parent?.article && context.parent?.url) {
        return "Du kan ikke lenke til både artikkel og ekstern URL";
      }
      return true; // Valid in all other cases
    }),
},
{
  title: "URL",
  name: "url",
  type: "string",
  description: "Lenke til en ekstern side",
  validation: (Rule) =>
    Rule.custom((value, context) => {
      // Show error if BOTH url and article are filled
      if (context.parent?.url && context.parent?.article) {
        return "Du kan ikke lenke til både ekstern URL og artikkel";
      }
      return true; // Valid in all other cases
    }),
},

Key changes:

  1. Use context.parent to access sibling fields (as explained in the Sanity validation docs)
  2. Return the error message string when the validation fails (both fields filled)
  3. Return true when validation passes (any other case)

The validation function should return:

  • true if the value is valid
  • A string error message if the value is invalid

You had these reversed in your original code, which is why it was blocking publishing even when validation should pass.

Show original thread
3 replies
Hi Knut. Are you saying you want there to be a warning message if both fields are filled out but you still want to be able to publish?
You can use document level validation but the warning is a bit out of the way (top-right corner), which is usually fine when it prevents a publish but in this case may go unseen.

fields: [...],
validation: Rule => Rule.custom(fields => (
  fields?.url && fields?.article ? "Du kan ikke lenke til både artikkel og ekstern URL" : true
)).warning()
Thank for your help! I want to prevent a user from being able to publish if both fields are filled out. So by changing
.warning()
to
.error("Some message her...")
, solved that.
Again, thanks for your help
😃

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?