Skip to content

fix: S3 upload silent skip when select projects out mimeType/filename#7

Open
deepshekhardas wants to merge 4 commits into
mainfrom
fix/16670-s3-select-projection
Open

fix: S3 upload silent skip when select projects out mimeType/filename#7
deepshekhardas wants to merge 4 commits into
mainfrom
fix/16670-s3-select-projection

Conversation

@deepshekhardas

@deepshekhardas deepshekhardas commented May 19, 2026

Copy link
Copy Markdown
Owner

Fixes payloadcms#16670

When a POST request uses ?select[…] to project mimeType/filename out of the response doc, the cloud-storage plugin silently skips uploading to S3.

Fix by falling back to req.file properties when data.filename/data.mimeType are undefined due to select projection. Also handle sizes fallback using payloadUploadSizes when data.sizes is missing.


Summary by cubic

Fixes silent S3 upload skips when ?select omits mimeType/filename by falling back to request file data. Also improves auth handling in plugin-mcp, lazy-loads drizzle-kit, and fixes localized status updates.

  • Bug Fixes
    • plugin-cloud-storage: fall back to req.file.name/req.file.mimetype when data.filename/data.mimeType are missing; use payloadUploadSizes when data.sizes is absent to avoid skipped uploads under ?select.
    • plugin-mcp: accept both payload-mcp-api-keys API-Key <key> and Bearer <key> authorization headers.
    • drizzle: lazy-load drizzle-kit in postgres/sqlite to prevent production bundling; update rows when only localized _status changes so the latest version is retrieved.

Written for commit 4158225. Summary will update on new commits. Review in cubic

Developer added 4 commits May 19, 2026 10:24
The MCP endpoint was accepting only Bearer token but Payload convention
uses 'payload-mcp-api-keys API-Key <key>' format. Now accepts both:
- 'payload-mcp-api-keys API-Key <key>' (Payload convention)
- 'Bearer <key>' (backwards compatible)

This makes the plugin consistent with other Payload API-key surfaces.

Fixes: payloadcms#16572
When using localizeStatus, the last version wasn't retrieved properly
when publishing directly. This is because the version_updatedAt and
version_createdAt weren't being set properly when publishing.

The fix adds a check for localized status (_status) in locales to
ensure main row data update happens even when only localized fields
have changed.

Fixes: payloadcms#16395
drizzle-kit/api was being required at module load time, causing it
to be included in production bundle for OpenNext Cloudflare and
other edge runtimes.

This moves the require() inside the function so it's only loaded
when actually needed (during migrations/schema push).

Also fixes the same issue in postgres adapter.

Fixes: payloadcms#16470
When a POST request uses ?select[…] to project mimeType/filename out of the
response doc, the cloud-storage plugin silently skips uploading to S3.

Fix by falling back to req.file properties when data.filename/data.mimeType
are undefined due to select projection. Also handle sizes fallback using
payloadUploadSizes when data.sizes is missing.

Closes payloadcms#16670

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

3 issues found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/drizzle/src/postgres/requireDrizzleKit.ts">

<violation number="1" location="packages/drizzle/src/postgres/requireDrizzleKit.ts:4">
P0: Temporal dead zone error: `require` is accessed before its `const` declaration. `const { createRequire } = require('module')` runs before `const require = createRequire(import.meta.url)`, so `require` is still in the TDZ and will throw a ReferenceError at runtime.</violation>
</file>

<file name="packages/drizzle/src/sqlite/requireDrizzleKit.ts">

<violation number="1" location="packages/drizzle/src/sqlite/requireDrizzleKit.ts:4">
P0: `require` is used on line 4 before it's declared on line 5. In this ESM module (`"type": "module"`), `require` is not a global, and the `const` declaration on line 5 puts it in the temporal dead zone, causing a ReferenceError at runtime. The original code kept the `createRequire` import at the top level (ESM import) and only created the require function inside — that ordering is required because you need `createRequire` before you can create `require`.</violation>
</file>

<file name="packages/plugin-cloud-storage/src/utilities/getIncomingFiles.ts">

<violation number="1" location="packages/plugin-cloud-storage/src/utilities/getIncomingFiles.ts:39">
P2: The `data.sizes ?? payloadUploadSizes` fallback is ineffective: `payloadUploadSizes` entries are Buffers, so `resizedFileData?.mimeType` is always missing and resized files are never added.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

const require = createRequire(import.meta.url)

export const requireDrizzleKit: RequireDrizzleKit = () => {
const { createRequire } = require('module')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0: Temporal dead zone error: require is accessed before its const declaration. const { createRequire } = require('module') runs before const require = createRequire(import.meta.url), so require is still in the TDZ and will throw a ReferenceError at runtime.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/drizzle/src/postgres/requireDrizzleKit.ts, line 4:

<comment>Temporal dead zone error: `require` is accessed before its `const` declaration. `const { createRequire } = require('module')` runs before `const require = createRequire(import.meta.url)`, so `require` is still in the TDZ and will throw a ReferenceError at runtime.</comment>

<file context>
@@ -1,10 +1,8 @@
-const require = createRequire(import.meta.url)
-
 export const requireDrizzleKit: RequireDrizzleKit = () => {
+  const { createRequire } = require('module')
+  const require = createRequire(import.meta.url)
   const {
</file context>

const require = createRequire(import.meta.url)

export const requireDrizzleKit: RequireDrizzleKit = () => {
const { createRequire } = require('module')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0: require is used on line 4 before it's declared on line 5. In this ESM module ("type": "module"), require is not a global, and the const declaration on line 5 puts it in the temporal dead zone, causing a ReferenceError at runtime. The original code kept the createRequire import at the top level (ESM import) and only created the require function inside — that ordering is required because you need createRequire before you can create require.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/drizzle/src/sqlite/requireDrizzleKit.ts, line 4:

<comment>`require` is used on line 4 before it's declared on line 5. In this ESM module (`"type": "module"`), `require` is not a global, and the `const` declaration on line 5 puts it in the temporal dead zone, causing a ReferenceError at runtime. The original code kept the `createRequire` import at the top level (ESM import) and only created the require function inside — that ordering is required because you need `createRequire` before you can create `require`.</comment>

<file context>
@@ -1,10 +1,8 @@
-const require = createRequire(import.meta.url)
-
 export const requireDrizzleKit: RequireDrizzleKit = () => {
+  const { createRequire } = require('module')
+  const require = createRequire(import.meta.url)
   const {
</file context>

if (data?.sizes) {
Object.entries(data.sizes).forEach(([key, resizedFileData]) => {
if (payloadUploadSizes?.[key] && resizedFileData.mimeType) {
const sizes = data?.sizes ?? payloadUploadSizes

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The data.sizes ?? payloadUploadSizes fallback is ineffective: payloadUploadSizes entries are Buffers, so resizedFileData?.mimeType is always missing and resized files are never added.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/plugin-cloud-storage/src/utilities/getIncomingFiles.ts, line 39:

<comment>The `data.sizes ?? payloadUploadSizes` fallback is ineffective: `payloadUploadSizes` entries are Buffers, so `resizedFileData?.mimeType` is always missing and resized files are never added.</comment>

<file context>
@@ -21,21 +21,25 @@ export function getIncomingFiles({
-    if (data?.sizes) {
-      Object.entries(data.sizes).forEach(([key, resizedFileData]) => {
-        if (payloadUploadSizes?.[key] && resizedFileData.mimeType) {
+    const sizes = data?.sizes ?? payloadUploadSizes
+    if (sizes) {
+      Object.entries(sizes).forEach(([key, resizedFileData]) => {
</file context>

@github-actions

Copy link
Copy Markdown

Pull Request titles must follow the Conventional Commits specification and have valid scopes.

The subject "S3 upload silent skip when select projects out mimeType/filename" found in the pull request title "fix: S3 upload silent skip when select projects out mimeType/filename"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.

feat(ui): add Button component
^    ^    ^
|    |    |__ Subject
|    |_______ Scope
|____________ Type

@jhb-dev

jhb-dev commented May 20, 2026

Copy link
Copy Markdown

Hi @deepshekhardas, thanks for creating this PR that would close the issue I opened.

However, I would recommend removing the unrelated MCP plugin and Drizzle changes to increase the likelihood that the team merges this PR. They are out of scope and belong to a new PR in my opinion.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: storage-s3 silently skips S3 upload when create request uses ?select[…] to project out mimeType

2 participants