Skip to content

fix: return 404 for version operations when versions are disabled - #18057

Merged
jacobsfletch merged 4 commits into
payloadcms:3.xfrom
apoorvdarshan:fix/disabled-global-versions
Oct 8, 2026
Merged

jacobsfletch merged 4 commits into
payloadcms:3.xfrom
apoorvdarshan:fix/disabled-global-versions

Conversation

@apoorvdarshan

Copy link
Copy Markdown

What?

Return an HTTP 400 response when global versions are requested for a global that does not have versions enabled.

Why?

The operation currently reaches the database adapter even though no versions table or model exists. SQL adapters can dereference a missing versions table, while MongoDB reports a missing model; both failures surface as an internal server error instead of explaining that the endpoint is unavailable for this global.

How?

  • Preserve the existing readVersions access check.
  • Reject disabled global versions before query validation and adapter access.
  • Add a REST regression test using the existing non-versioned global fixture.

Fixes #18056

Testing

  • pnpm run test:int globals — 14 passed
  • pnpm run build:payload — successful
  • Prettier check on both changed files — passed
  • ESLint on the changed production file — 0 errors (1 pre-existing warning)

@jacobsfletch jacobsfletch left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look at this @apoorvdarshan! Same comment as here: #18618 (review). We need to apply the same to collections as well, and call it sooner.

Edit: I went ahead and made these changes in ba07af5

@jacobsfletch jacobsfletch changed the title fix: handle disabled global versions requests fix: return 404 for version operations when versions are disabled Oct 8, 2026
…al-versions-3x

# Conflicts:
#	test/versions/config.ts
#	test/versions/int.spec.ts
#	test/versions/slugs.ts
@jacobsfletch
jacobsfletch enabled auto-merge (squash) October 8, 2026 14:45
jacobsfletch added a commit that referenced this pull request Oct 8, 2026
…8618)

### What?

`GET /api/globals/<slug>/versions` (and `/versions/:id`) on a global
with **versions disabled** returns HTTP 500 with `TypeError: Cannot read
properties of undefined (reading 'id')` from the drizzle adapter. This
PR makes it return a clean **404 Not Found**.

This targets `main`. The open PR #18057 covers `3.x`. The bug matters
more on `main`, because the website template ships `versions: false`
globals (Header/Footer) while globals default to versioned.

### Why?

`findVersionsOperation` and `findVersionByIDOperation` call
`payload.db.findGlobalVersions` without checking
`globalConfig.versions`. A global without versions has no versions
table, so the drizzle adapter resolves `tableName` to `undefined` and
crashes in `findMany`. Any authenticated user with `readVersions` access
could trigger a 500 on a documented REST route.

### How?

After the access check, both operations now throw `NotFound` when
`globalConfig.versions` is falsy:

```ts
if (!globalConfig.versions) {
  throw new NotFound(req.t)
}
```

`findVersionByID` returns `null` instead when `disableErrors` is set,
which matches how it already handles a missing version. The check runs
after access, so an unauthenticated caller still gets 403 first and the
response does not reveal anything new.

404 matches how the other "this resource doesn't exist" cases behave in
the global version operations (`findVersionByID`, `restoreVersion`).

**Tests:** I added a non-versioned global (`versions: false`) to
`test/versions` and four int tests under "Globals - versions disabled":
- Local API `findGlobalVersions` / `findGlobalVersionByID` throw
`NotFound`
- REST `GET /globals/<slug>/versions` and `/versions/1` return 404

Before the fix, all four failed with the TypeError from the issue
(SQLite/drizzle). After the fix they pass, and the rest of
`test/versions/int.spec.ts` passes.

Fixes #18056

---------

Co-authored-by: Jake Fletcher <jacobsfletch@gmail.com>
@jacobsfletch
jacobsfletch merged commit d72c669 into payloadcms:3.x Oct 8, 2026
338 of 342 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🚀 This is included in version v3.91.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants