You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[overlay] incorrectly concatenates enum arrays during deep merge #792
When using bump overlay to apply an overlay that adds new properties to a schema, enum arrays from nested properties are incorrectly appended to existing enum arrays at different paths, resulting in duplicate values.
Environment
bump-cli version: 2.9.8
Node.js version: 24.x
Steps to Reproduce
Have an OpenAPI spec with a property containing an enum:
The top-level method.enum should remain unchanged with 4 values:
method:
enum: [GET, POST, PUT, DELETE]
And a new request.properties.method.enum should be added with 4 values.
Actual Behavior
The top-level method.enum is incorrectly modified to have 8 values (duplicated):
method:
enum: [GET, POST, PUT, DELETE, GET, POST, PUT, DELETE]
Root Cause
In src/core/overlay.ts, the update method uses mergician with appendArrays: true:
constmerger=mergician({appendArrays: true});
This causes arrays to be concatenated during deep merge. When the overlay adds a nested property with the same name (method) containing an enum array, mergician appears to find and concatenate enum arrays from different schema paths.
I've tried the example definitions of your issue description in both a test case and manually by running the current CLI code (I also tested with version 2.9.8) and could not reproduce. You can see the test files in this commit.
And the output:
I'm not sure to understand where the issue lies. Could you elaborate please?
Hi @paulRbr, thanks for testing! Here's a simpler, directly reproducible example:
# base-spec.yaml:openapi: 3.1.0info:
title: Test APIversion: 1.0.0paths:
/pets/{petId}:
put:
summary: Update a petoperationId: updatePetparameters:
- name: petIdin: pathrequired: trueschema:
type: stringrequestBody:
content:
application/json:
schema:
type: objectproperties:
name:
type: stringdescription: The pet's name.status:
type: stringdescription: The pet's status.enum:
- available
- pending
- soldresponses:
'200':
description: OK
# overlay.yaml:overlay: 1.0.0info:
title: Add fields to updatePetversion: 1.0.0actions:
- target: >- $.paths['/pets/{petId}'] .put .requestBody .content['application/json'] .schema .properties update: name: type: string description: Updated name of the pet. status: type: string description: Updated status of the pet. enum: - available - pending - sold tag: type: string description: A tag for the pet.
status:
enum:
- available
- pending
- sold
- available
- pending
- sold
The key is that the overlay targets .properties (an object)
and updates a property (status) that already exists in the
base spec with the same enum values. Since mergician({appendArrays: true}) deep-merges the overlay's
status object into the base's status object, the enum arrays
get concatenated instead of replaced.
Thanks @garciasdos for you answer. So basically you expect array merging to also apply uniqueness on the result.
I have to admit this is not well specified in the Overlay specification, and maybe in most cases it does make sense. However I'm afraid that behavior is arbitrary depending on the use case.
Imagine such a merge:
Base document (and target object)
groceries:
- banana
- tomato
Overlay update
update:
groceries:
- banana
- onions
Would one want to result with:
grocieries:
- banana
- tomato
- banana
- onions
or
grocieries:
- banana
- tomato
- onions
It really depends if you expect to keep the count of each occurrence.
Anyway, I'm ok with changing the default behavior to deduplicate array values as you suggest in #791. Let's see if other users have different usecases and we'll adapt then!
@paulRbr Thanks for applying the fix! Just a small clarification worth noting: deduplication here isn't just a matter of preferred default behavior — the OpenAPI/JSON Schema specification actually requires it.
The JSON Schema spec explicitly states that enum must be "an array with at least one element, where each element is unique" (source). This means a spec with duplicate enum values is technically invalid, so any tool applying overlays that result in duplicated enum entries would produce a non-conformant document.
Thanks for pointing that out. Indeed for enum arrays in JSON schema that would be the case. However Overlay don't act only on those arrays. They can merge any type of arrays but I agree that it's safer to act with deduped arrays by default.
Thanks again for your analysis and fix. We will release a new version of the CLI this week.
Activity
fbraure commentedon Feb 5, 2026
Thank you very much for pointing this out, creating an Issue and proposing a fix.
paulRbr commentedon Feb 10, 2026
Hi @garciasdos, thanks for your contribution.
I've tried the example definitions of your issue description in both a test case and manually by running the current CLI code (I also tested with version 2.9.8) and could not reproduce. You can see the test files in this commit.
And the output:
I'm not sure to understand where the issue lies. Could you elaborate please?
garciasdos commentedon Feb 23, 2026
Hi @paulRbr, thanks for testing! Here's a simpler, directly reproducible example:
Running bump overlay base-spec.yaml overlay.yaml produces duplicated enums:
The key is that the overlay targets
.properties(an object)and updates a property (status) that already exists in the
base spec with the same enum values. Since
mergician({appendArrays: true})deep-merges the overlay'sstatus object into the base's status object, the enum arrays
get concatenated instead of replaced.
Tested with bump-cli 2.9.10.
paulRbr commentedon Feb 23, 2026
Thanks @garciasdos for you answer. So basically you expect array merging to also apply uniqueness on the result.
I have to admit this is not well specified in the Overlay specification, and maybe in most cases it does make sense. However I'm afraid that behavior is arbitrary depending on the use case.
Imagine such a merge:
Base document (and target object)
Overlay update
Would one want to result with:
or
It really depends if you expect to keep the count of each occurrence.
Anyway, I'm ok with changing the default behavior to deduplicate array values as you suggest in #791. Let's see if other users have different usecases and we'll adapt then!
garciasdos commentedon Feb 23, 2026
@paulRbr Thanks for applying the fix! Just a small clarification worth noting: deduplication here isn't just a matter of preferred default behavior — the OpenAPI/JSON Schema specification actually requires it.
The JSON Schema spec explicitly states that enum must be "an array with at least one element, where each element is unique" (source). This means a spec with duplicate enum values is technically invalid, so any tool applying overlays that result in duplicated enum entries would produce a non-conformant document.
paulRbr commentedon Feb 24, 2026
Thanks for pointing that out. Indeed for
enumarrays in JSON schema that would be the case. However Overlay don't act only on those arrays. They can merge any type of arrays but I agree that it's safer to act with deduped arrays by default.Thanks again for your analysis and fix. We will release a new version of the CLI this week.
paulRbr commentedon Apr 11, 2026
Here's a use case where array duplication is necessary #818
So we need to find a better way to do so. (Probably apply the deduplication only on enum fields)