@@ -199,15 +199,51 @@ export class OpenAPIMockValidator {
199199 this . addAdditionalPropertiesFalse ( schema . items as Record < string , unknown > ) ;
200200 }
201201
202- // Recurse into composition keywords
203- for ( const keyword of [ 'allOf' , ' oneOf', 'anyOf' ] ) {
202+ // Recurse into oneOf/anyOf branches
203+ for ( const keyword of [ 'oneOf' , 'anyOf' ] ) {
204204 if ( Array . isArray ( schema [ keyword ] ) ) {
205205 for ( const branch of schema [ keyword ] as Record < string , unknown > [ ] ) {
206206 this . addAdditionalPropertiesFalse ( branch ) ;
207207 }
208208 }
209209 }
210210
211+ // For allOf: merge sibling properties before recursing so each branch
212+ // knows about properties defined in other branches. Without this,
213+ // additionalProperties:false on branch A rejects properties from branch B.
214+ if ( Array . isArray ( schema . allOf ) ) {
215+ const branches = schema . allOf as Record < string , unknown > [ ] ;
216+
217+ // Collect the union of all property keys across all allOf branches
218+ const allPropertyKeys = new Set < string > ( ) ;
219+ for ( const branch of branches ) {
220+ if ( branch . properties && typeof branch . properties === 'object' ) {
221+ for ( const key of Object . keys ( branch . properties as Record < string , unknown > ) ) {
222+ allPropertyKeys . add ( key ) ;
223+ }
224+ }
225+ }
226+
227+ // Inject empty stubs for missing sibling properties into each branch
228+ if ( allPropertyKeys . size > 0 ) {
229+ for ( const branch of branches ) {
230+ if ( branch . properties && typeof branch . properties === 'object' ) {
231+ const props = branch . properties as Record < string , unknown > ;
232+ for ( const key of allPropertyKeys ) {
233+ if ( ! ( key in props ) ) {
234+ props [ key ] = { } ;
235+ }
236+ }
237+ }
238+ }
239+ }
240+
241+ // Now recurse into each branch
242+ for ( const branch of branches ) {
243+ this . addAdditionalPropertiesFalse ( branch ) ;
244+ }
245+ }
246+
211247 return schema ;
212248 }
213249
0 commit comments