serverless/serverless · error · ServerlessError
LEGACY_CONFIGURATION_PROPERTY_MERGE_INVALID_INPUT
LEGACY_CONFIGURATION_PROPERTY_MERGE_INVALID_INPUT
Error message
Non-object value specified in ${key} array: ${value} What it means
`mergeArrays` supports a legacy form where `resources` or `functions` is an array of objects to deep-merge with lodash `_.merge`. If any element of that array is truthy but not an object (a string, number, etc.), the merge cannot proceed and this error throws. Falsy elements are silently skipped.
Source
Thrown at packages/serverless/lib/classes/service.js:246
this.functions[functionName].events = []
}
if (!functionObj.name) {
this.functions[functionName].name =
`${this.service}-${stageNameForFunction}-${functionName}`
}
})
}
mergeArrays() {
;['resources', 'functions'].forEach((key) => {
if (Array.isArray(this[key])) {
this[key] = this[key].reduce((memo, value) => {
if (value) {
if (typeof value === 'object') {
return _.merge(memo, value)
}
throw new ServerlessError(
`Non-object value specified in ${key} array: ${value}`,
'LEGACY_CONFIGURATION_PROPERTY_MERGE_INVALID_INPUT',
)
}
return memo
}, {})
}
})
}
async validate() {
const userConfig = this.initialServerlessConfig
// Ensure to validate normalized (after mergeArrays) input
if (userConfig.functions) userConfig.functions = this.functions
if (userConfig.resources) userConfig.resources = this.resources
View on GitHub (pinned to b9d7ea51c8)
Solutions
- Ensure every element of the `resources`/`functions` array is an object.
- Move descriptive strings into a `Description:` CloudFormation property inside an object, not as a bare array item.
- Use `serverless print` to dump the array and find the offending scalar element.
Example fix
# before
resources:
- 'my stack'
- Resources:
MyBucket:
Type: AWS::S3::Bucket
# after
resources:
- Description: 'my stack'
- Resources:
MyBucket:
Type: AWS::S3::Bucket Defensive patterns
Strategy: validation
Validate before calling
for (const key of ['resources', 'functions']) {
if (Array.isArray(config[key])) {
config[key].forEach((el, i) => {
if (el && typeof el !== 'object') {
throw new Error(`${key}[${i}] must be an object, got ${typeof el}`)
}
})
}
} Type guard
const isValidArrayForm = (v) => !Array.isArray(v) || v.every((el) => el == null || typeof el === 'object')
Try / catch
try {
service.mergeArrays()
} catch (e) {
if (e.code === 'LEGACY_CONFIGURATION_PROPERTY_MERGE_INVALID_INPUT') { console.error('Remove non-object entries from resources/functions arrays'); process.exit(1) }
throw e
} Prevention
- Prefer the modern object form of resources/functions over the legacy array form.
- If using array form for composition, keep every element a CloudFormation fragment object.
- Move free-text descriptions into a `Description:` property inside an object.
When it happens
Trigger: `resources: [...]` or `functions: [...]` where at least one element is a non-null primitive, e.g. `resources: ['description', { Resources: {...} }]`.
Common situations: Composing multiple CloudFormation snippet files where one file accidentally exports a string comment; YAML lists that mixed a scalar header with object fragments; hand-merged configs from pull requests that pasted a string into the resources array.
Related errors
- NON_OBJECT_FUNCTIONS_CONFIGURATION
- NON_OBJECT_FUNCTION_CONFIGURATION_ERROR
- FUNCTION_EVENT_SCHEMA_NOT_OBJECT
- DUPLICATE_PLUGIN_DEFINITION
- INVALID_COMMAND_MISSING_SERVICE_DIRECTORY
AI-assisted analysis of serverless/serverless@b9d7ea51c8 (2026-08-13).
Data as JSON: /api/errors/4c48a89f0711d395.
Report an issue: GitHub.