Describe the Bug
Invalid UUID values in an equals filter appear to be sanitized to null, which then changes the meaning of the query to IS NULL.
We noticed this with a UUID relationship field, but this may affect UUID columns more generally.
In our case:
equals: "<valid UUID with matching documents>" returns the correct documents.
equals: "<valid UUID with no matching documents>" returns an empty docs array.
equals: "invalid-something" returns documents where the relationship field is null.
We are not fully sure what the intended behavior should be. Possible expected behavior could be:
- Throw a query validation error because
"invalid-something" is not a valid UUID.
- Return no results, matching the behavior of a valid UUID that simply does not match anything.
But returning documents where the field is null seems unexpected, because the caller asked for equals: "invalid-something", not equals: null.
This may be related to the UUID sanitization added in #8369.
In @payloadcms/drizzle, sanitizeQueryValue appears to convert invalid UUID strings to null:
if (isUUID && typeof formattedValue === 'string') {
if (!uuidValidate(val)) {
formattedValue = null
}
}
Then later in parseParams, equals with a null query value is interpreted as IS NULL:
if (operator === 'equals' && queryValue === null) {
constraints.push(isNull(resolvedColumn))
break
}
So the effective query becomes "column is null".
There also seems to be a related issue when multiple operators are provided on the same field. If equals is processed first and becomes IS NULL, the break means another operator like exists: true may not be applied.
Link to the code that reproduces this issue
https://github.com/tobiasvdorp/payload-uuid-treated-as-null-issue-repro
Reproduction Steps
- Create a collection with a relationship field:
{
name: 'articleType',
type: 'relationship',
relationTo: 'article-types',
hasMany: false,
}
- Configure Postgres with UUID ids:
postgresAdapter({
idType: 'uuid',
})
-
Create at least one document where the relationship field is empty (null).
-
Query with a syntactically valid UUID that has no matching documents. This returns an empty docs array as expected:
query {
Articles(
where: {
articleType: {
equals: "valid-article-type-uuid" // replace with actual UUID of existing articleType
}
}
) {
docs {
id
articleType {
id
}
}
}
}
- Query with a value that is not a valid UUID:
query {
Articles(
where: {
articleType: {
equals: "invalid-something"
}
}
) {
docs {
id
articleType {
id
}
}
}
}
-
Observe that the query returns documents where articleType is null.
-
Optionally add exists: true on the same field:
query {
Articles(
where: {
articleType: {
equals: "invalid-something"
exists: true
}
}
) {
docs {
id
articleType {
id
}
}
}
}
- Observe that this does not appear to prevent the
null relationship documents from being returned in our case.
Which area(s) are affected?
area: graphql, area: core, db: postgres, db: mongodb
Environment Info
Binaries:
Node: 22.17.1
npm: 10.9.2
Yarn: N/A
pnpm: 10.33.0
Relevant Packages:
payload: 3.82.1
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:15 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6000
Available memory (MB): 32768
Available CPU cores: 10
Describe the Bug
Invalid UUID values in an
equalsfilter appear to be sanitized tonull, which then changes the meaning of the query toIS NULL.We noticed this with a UUID relationship field, but this may affect UUID columns more generally.
In our case:
equals: "<valid UUID with matching documents>"returns the correct documents.equals: "<valid UUID with no matching documents>"returns an emptydocsarray.equals: "invalid-something"returns documents where the relationship field isnull.We are not fully sure what the intended behavior should be. Possible expected behavior could be:
"invalid-something"is not a valid UUID.But returning documents where the field is
nullseems unexpected, because the caller asked forequals: "invalid-something", notequals: null.This may be related to the UUID sanitization added in #8369.
In
@payloadcms/drizzle,sanitizeQueryValueappears to convert invalid UUID strings tonull:Then later in
parseParams,equalswith anullquery value is interpreted asIS NULL:So the effective query becomes "column is null".
There also seems to be a related issue when multiple operators are provided on the same field. If
equalsis processed first and becomesIS NULL, thebreakmeans another operator likeexists: truemay not be applied.Link to the code that reproduces this issue
https://github.com/tobiasvdorp/payload-uuid-treated-as-null-issue-repro
Reproduction Steps
Create at least one document where the relationship field is empty (
null).Query with a syntactically valid UUID that has no matching documents. This returns an empty
docsarray as expected:Observe that the query returns documents where
articleTypeisnull.Optionally add
exists: trueon the same field:nullrelationship documents from being returned in our case.Which area(s) are affected?
area: graphql, area: core, db: postgres, db: mongodb
Environment Info