payloadcms/payload · error · APIError
Invalid field path.
Error message
Invalid field path.
What it means
In setNestedValue, getPathKey validates array indices. It throws APIError 'Invalid field path.' when an index is out of bounds: if a source array is provided and index >= source.length, or without a source when index > target.length + 1 (MAX_UNVERIFIED_SPARSE_ARRAY_GAP). This prevents creating huge sparse arrays from untrusted paths.
Source
Thrown at packages/plugin-import-export/src/utilities/setNestedValue.ts:34
return Number.isSafeInteger(index) && index >= 0
}
const getPathKey = (
target: Record<string, unknown> | unknown[],
part: string,
source: unknown,
): number | string => {
if (!Array.isArray(target) || !isArrayIndex(part)) {
return part
}
const index = Number(part)
if (
(Array.isArray(source) && index >= source.length) ||
(!Array.isArray(source) && index > target.length + MAX_UNVERIFIED_SPARSE_ARRAY_GAP)
) {
throw new APIError('Invalid field path.', 400, null, true)
}
return index
}
const getSourceValue = (source: unknown, part: string): unknown => {
if (source === null || typeof source !== 'object') {
return undefined
}
const key = Array.isArray(source) && isArrayIndex(part) ? Number(part) : part
return (source as Record<number | string, unknown>)[key]
}
/**
* Sets a value deeply into a nested object or array, based on a dot-notation path.
*View on GitHub (pinned to 00c58b35c0)
Solutions
- Validate array indices against the source array length before building the path.
- Reject/normalize indices that exceed target.length + 1 when no source is available.
- Sanitize untrusted paths to clamp out-of-range indices.
Defensive patterns
Strategy: validation
Validate before calling
function assertPathWithinSource(path: string, source: unknown) {
const parts = path.split('.')
let cur: unknown = source
for (const p of parts) {
if (Array.isArray(cur) && /^\d+$/.test(p) && Number(p) >= cur.length) {
throw new Error(`Array index ${p} out of bounds (len ${cur.length})`)
}
cur = Array.isArray(cur) || (cur && typeof cur === 'object') ? (cur as Record<string, unknown>)?.[p] : undefined
}
} Type guard
const isWithinArrayBounds = (index: number, source: unknown): boolean => !Array.isArray(source) || index < source.length
Prevention
- Validate array indices against the source array length before building paths.
- Clamp or reject indices beyond target.length + 1 when no source exists.
- Treat reconstructed paths from untrusted input as untrusted.
When it happens
Trigger: A dot path like 'items.999.field' where the source array is short (index >= source.length), or a large index with no source to validate against (exceeds the allowed sparse gap).
Common situations: Reconstructing nested objects from flattened CSV rows with array fields; untrusted path input with arbitrary indices; mismatch between source array length and the target path.
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/a596c2224f45be07.
Report an issue: GitHub.