payloadcms/payload · error · APIError
Invalid field path.
Error message
Invalid field path.
What it means
getSelect builds a Payload select object from dot-notation field paths. Before traversing, it rejects any path whose segments include __proto__, constructor, or prototype (hasUnsupportedFieldPathSegment). This is a prototype-pollution guard; the 400 is intentional and security-relevant.
Source
Thrown at packages/plugin-import-export/src/utilities/getSelect.ts:24
const createSelect = (): SelectIncludeType => Object.create(null) as SelectIncludeType
/**
* Takes an input of array of string paths in dot notation and returns a select object.
* Used for both export and import to build Payload's select query format.
*
* @example
* getSelect(['id', 'title', 'group.value', 'createdAt', 'updatedAt'])
* // Returns: { id: true, title: true, group: { value: true }, createdAt: true, updatedAt: true }
*/
export const getSelect = (fields: string[]): SelectIncludeType => {
const select = createSelect()
fields.forEach((field) => {
const segments = field.split('.')
if (hasUnsupportedFieldPathSegment(segments)) {
throw new APIError('Invalid field path.', 400, null, true)
}
let selectRef = select
segments.forEach((segment, i) => {
if (i === segments.length - 1) {
selectRef[segment] = true
} else {
if (!Object.prototype.hasOwnProperty.call(selectRef, segment)) {
selectRef[segment] = createSelect()
}
selectRef = selectRef[segment] as SelectIncludeType
}
})
})
return select
}View on GitHub (pinned to 00c58b35c0)
Solutions
- Sanitize field paths: strip/reject __proto__, constructor, prototype before calling getSelect.
- Do not pass untrusted user input directly as the fields array; allowlist field names.
- Validate paths against the collection's known field names.
Example fix
// before const select = getSelect(userSuppliedFields) // after const SAFE = /__proto__|constructor|prototype/ const safeFields = userSuppliedFields.filter((f) => !SAFE.test(f)) const select = getSelect(safeFields)
Defensive patterns
Strategy: validation
Validate before calling
const UNSUPPORTED = new Set(['__proto__', 'constructor', 'prototype'])
function sanitizeFields(fields: string[]): string[] {
return fields.filter((f) => !f.split('.').some((seg) => UNSUPPORTED.has(seg)))
}
const select = getSelect(sanitizeFields(userFields)) Type guard
const isSafeFieldPath = (path: string): boolean =>
!path.split('.').some((seg) => UNSUPPORTED.has(seg)) Prevention
- Never pass raw user input as the fields array; allowlist against schema field names.
- Strip prototype-polluting segments at the trust boundary.
- Add a unit test that getSelect rejects __proto__/constructor/prototype.
When it happens
Trigger: A field path contains a dangerous segment, e.g. '__proto__.x', 'constructor.prototype', or a CSV/export field list sourced from untrusted input that includes such keys.
Common situations: Export/import field selection driven by user-supplied query params; CSV headers that happen to be '__proto__'; mapping table built from external data.
Related errors
- Invalid field path.
- ${value} is not allowed as a JSON query value
- Invalid path segment. Only alphanumeric characters and under
- File type ${mimeTypeFromExtension} (from extension ${typeFro
- The provided URL is not allowed.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/83b79910e2ba05b9.
Report an issue: GitHub.