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 = nullView on GitHub (pinned to 00c58b35c0)
Solutions
- Verify the slug in the URL matches a collection defined with an `upload` block in your Payload config.
- Add `upload: { staticDir: '...' }` to that collection's config if files should be served from it.
- Check the frontend URL builder to ensure it only emits file URLs for actual upload collections.
- 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
- Centralize file-URL construction in a helper that only emits for upload collections.
- Type your collection slugs as a union of known upload slugs.
- Document which collections are upload collections.
- Add a CI check that file URLs are only built against collections with upload config.
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
- Upload collection ${upload.collectionSlug} was not found
- storage contains an invalid entry: expected an object with a
- Field ${field.label} has reserved name '${fieldName}'.
- Field "${field.name}" of type "${field.type}" has an empty r
- Field ${field.label} has invalid relationship '${relationshi
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/23eb3a30e3c65264.
Report an issue: GitHub.