payloadcms/payload · error · APIError

This collection is not an upload collection: ${collection.co

Error message

This collection is not an upload collection: ${collection.config.slug}

What it means

APIError (HTTP 400) thrown by the getFileHandler when the resolved collection has no `upload` property in its config. The GET /api/:collection/file/:filename route only serves upload collections; any other collection slug is rejected before filename/access processing.

Source

Thrown at packages/payload/src/uploads/endpoints/getFile.ts:25

import type { PayloadHandler } from '../../config/types.js'

import { APIError } from '../../errors/APIError.js'
import { checkFileAccess } from '../../uploads/checkFileAccess.js'
import { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'
import { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'
import { parseRangeHeader } from '../../uploads/parseRangeHeader.js'
import { getRequestCollection } from '../../utilities/getRequestEntity.js'
import { headersWithCors } from '../../utilities/headersWithCors.js'

export const getFileHandler: PayloadHandler = async (req) => {
  const collection = getRequestCollection(req)

  const filename = req.routeParams?.filename as string
  const prefix = req.searchParams?.get('prefix') ?? undefined

  if (!collection.config.upload) {
    throw new APIError(
      `This collection is not an upload collection: ${collection.config.slug}`,
      httpStatus.BAD_REQUEST,
    )
  }

  const accessResult = (await checkFileAccess({
    collection,
    filename,
    prefix,
    req,
  }))!

  if (accessResult instanceof Response) {
    return accessResult
  }

  if (collection.config.upload.handlers?.length) {
    let customResponse: null | Response | void = null

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Verify the slug in the URL matches a collection defined with an `upload` block in your Payload config.
  2. Add `upload: { staticDir: '...' }` to that collection's config if files should be served from it.
  3. Check the frontend URL builder to ensure it only emits file URLs for actual upload collections.
  4. Confirm the route prefix matches your config.admin.user or custom routes if you customized them.

Example fix

// before — collection without upload
{ slug: 'docs', fields: [ { name: 'file', type: 'text' } ] }
// after — make it an upload collection
{ slug: 'docs', upload: { staticDir: 'docs' }, fields: [ { name: 'file', type: 'upload' } ] }
Defensive patterns

Strategy: type-guard

Validate before calling

const UPLOAD_SLUGS = Object.entries(payload.config.collections)
  .filter(([, c]) => Boolean(c.upload))
  .map(([slug]) => slug)
function isUploadSlug(slug: string): boolean {
  return UPLOAD_SLUGS.includes(slug)
}
// before building a file URL:
if (!isUploadSlug(slug)) throw new Error(`${slug} is not an upload collection`)

Type guard

const isUploadCollectionConfig = (c: { upload?: unknown }): boolean =>
  Boolean(c && typeof c === 'object' && 'upload' in c && c.upload)

Try / catch

try {
  const res = await fetch(`/api/${slug}/file/${filename}`)
  if (res.status === 400) {
    const body = await res.json()
    if (/not an upload collection/.test(body.errors?.[0]?.message ?? '')) {
      console.error('Wrong collection slug — not an upload collection')
    }
  }
} catch (e) { /* network */ }

Prevention

When it happens

Trigger: GET request to /api/<slug>/file/<filename> (or /api/<slug>/id/<id>/<filename>) where <slug> resolves to a collection whose config lacks an `upload` block — e.g. a plain global, a blog-posts collection defined without upload, or a typo in the slug.

Common situations: Wrong collection slug in a URL (typo, stale frontend link); accessing the file route of a collection that stores file metadata but uses an external storage plugin without the upload field; misconfigured reverse proxy routing file requests to the wrong collection; frontend building URLs from a non-upload collection.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/23eb3a30e3c65264. Report an issue: GitHub.