payloadcms/payload · error · APIError

Collection "${collectionSlug}" does not support file uploads

Error message

Collection "${collectionSlug}" does not support file uploads.

What it means

Thrown as a 400 when `resolveFile` is asked to handle a file for a collection whose config has no `upload` block — i.e. the target collection is not a Payload upload collection, so there is no `uploadConfig` to read `pasteURL`, file size limits, or storage adapters from.

Source

Thrown at packages/plugin-mcp/src/mcp/builtin/collections/fileInput.ts:73

  if (input.source === 'uploadReference') {
    try {
      return await getFileFromUploadInstructions({ collectionSlug, file: input.file, req })
    } catch (error) {
      if (error instanceof Error && error.message === 'Staged upload was not found.') {
        throw new APIError(
          'Staged upload not found. Complete the upload action first, or use base64 for small local files.',
          400,
        )
      }
      throw error
    }
  }

  const uploadConfig = req.payload.collections[collectionSlug]?.config.upload

  if (!uploadConfig) {
    throw new APIError(`Collection "${collectionSlug}" does not support file uploads.`, 400)
  }

  const maxFileSize = req.payload.config.upload.limits?.fileSize
  let file: File

  if (input.source === 'base64') {
    const data = decodeBase64({ maxFileSize, value: input.data })

    file = {
      name: sanitizeFilename(input.name),
      data,
      mimetype: input.mimeType,
      size: data.length,
    }
  } else {
    if (uploadConfig.pasteURL === false) {
      throw new APIError(
        `Uploading files from URLs is disabled for collection "${collectionSlug}".`,

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Confirm the collection slug is correct and the collection is configured with an `upload` block in Payload
  2. If the collection should accept files, add an `upload` config (with `staticURL`, `staticDir`, etc.) to it
  3. Restrict the MCP tool's allowed collections so non-upload collections cannot be targeted

Example fix

// before — collection without upload
{ slug: 'notes', fields: [...] }
// after — enable uploads
{ slug: 'notes', upload: { staticURL: '/media', staticDir: 'media' }, fields: [...] }
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the collection is an upload collection before calling a file tool
const col = payload.config.collections.find(c => c.slug === slug)
if (!col?.upload) throw new Error(`${slug} is not an upload collection`)

Type guard

import type { CollectionConfig } from 'payload'
function isUploadCollection(c: CollectionConfig | undefined): c is CollectionConfig & { upload: NonNullable<CollectionConfig['upload']> } {
  return !!c && !!c.upload
}

Try / catch

import { APIError } from 'payload'
try {
  await fileTool.call({ collectionSlug: slug, ... })
} catch (e) {
  if (e instanceof APIError && e.statusCode === 400 && /does not support file uploads/.test(e.message)) {
    // route to a non-file create flow instead
  }
  throw e
}

Prevention

When it happens

Trigger: Calling an MCP file tool against a collection slug whose `CollectionConfig` lacks an `upload` property; passing a non-upload collection slug (e.g. a plain relationship collection) to a tool that ultimately calls `resolveFile`.

Common situations: Typo in the `collectionSlug` argument; pointing the tool at a collection that was originally an upload collection but had its `upload` block removed; misconfiguring which collections the MCP plugin exposes file tools for.

Related errors


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