Querying archived posts in Sanity.io causing unexpected results
This is a common gotcha with GROQ's inequality operator! The issue you're experiencing comes down to how GROQ handles null values in filter expressions.
When you use isArchived != true, here's what happens:
- If
isArchivedisfalse, the expression evaluates totrueβ (document matches) - If
isArchivedistrue, the expression evaluates tofalse(document is filtered out) - If
isArchivedisnullor undefined, the expression evaluates tonull
The key problem is that when a filter expression returns null, GROQ treats it as falsy and filters out that document. However, the behavior can be inconsistent or confusing because null in boolean contexts doesn't always behave as you'd expect, and the != operator specifically returns null when comparing with null values.
So isArchived != true should theoretically work, but the way null is handled in filter contexts can lead to unexpected results. This is why your working solutions are more reliable:
Option 1: Explicit false check
*[_type == "post" && isArchived == false]This explicitly matches documents where isArchived is exactly false. Documents where the field is null or undefined will NOT match (because null == false returns null, which is falsy in filters).
Option 2: Negation operator (recommended)
*[_type == "post" && !isArchived]This is the most idiomatic approach in GROQ. The ! operator will evaluate to true for false, null, and undefined values, so it includes all non-archived posts regardless of whether the field exists.
Option 3: Explicit null handling
If you want to be very specific about which documents to include, you can use the defined() function:
*[_type == "post" && (!defined(isArchived) || isArchived == false)]This explicitly includes posts where isArchived doesn't exist OR is false.
For most use cases with a boolean "archived" flag, !isArchived is your best bet - it's clean, readable, and treats missing values the same as false, which is typically what you want for feature flags like this.
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.