Skip to content

Incorrect string/array min value in MSW mocks when only maxLength/maxItems is specified #3121

Description

@youngcm2

Description

When generating MSW mocks, if a schema specifies only maxLength (without minLength) or only maxItems (without minItems), the generator incorrectly falls back to the global stringMin/arrayMin default for the unspecified bound.

With the default stringMin: 10, a schema with maxLength: 5 produces:

faker.string.alpha({ length: { min: 10, max: 5 } })

min > max causes faker to throw at runtime. Even when maxLength >= 10, it is semantically wrong — the schema implies no minimum constraint, but the global default is applied anyway. The same issue occurs symmetrically: minLength without maxLength causes the global stringMax to be used as the upper bound, which may be less than minLength.

Configuration (orval.config)

import { defineConfig } from 'orval';

export default defineConfig({
  api: {
    output: {
      target: './src/api/endpoints.ts',
      mock: { type: 'msw' },
    },
    input: { target: './openapi.yaml' },
  },
});

Environment

Run the command above and paste the output here.

Expected behavior

When only maxLength: 5 is set, the generated mock should use only an upper bound:

faker.string.alpha({ length: { max: 5 } })

When only minLength: 30 is set:

faker.string.alpha({ length: { min: 30 } })

Global defaults (stringMin, stringMax, arrayMin, arrayMax) should only be applied when neither bound is specified in the schema.

Actual behavior

With maxLength: 5 and the default stringMin: 10:

faker.string.alpha({ length: { min: 10, max: 5 } })
// ⚠️ faker throws — min > max

OpenAPI document (minimal, if applicable)

openapi: 3.0.3
info:
  title: Demo
  version: 0.0.0
paths:
  /items:
    get:
      operationId: getItems
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  shortCode:
                    type: string
                    maxLength: 5
                  longDescription:
                    type: string
                    minLength: 30
                  tags:
                    type: array
                    maxItems: 2
                    items:
                      type: string

Additional context

The bug is in packages/mock/src/faker/getters/scalar.ts. The fix is to conditionally apply global defaults only when neither bound is schema-specified:

// Before
const strMin = (item.minLength ?? safeMockOptions.stringMin) as number | undefined;
const strMax = (item.maxLength ?? safeMockOptions.stringMax) as number | undefined;

// After
const strMin = (item.minLength ?? (item.maxLength !== undefined ? undefined : safeMockOptions.stringMin)) as number | undefined;
const strMax = (item.maxLength ?? (item.minLength !== undefined ? undefined : safeMockOptions.stringMax)) as number | undefined;

Fix is available in PR #3120.

Metadata

Metadata

Assignees

Labels

mswMSW related issues

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions