Describe the bug
When a ChoiceField is used as a query parameter via @extend_schema(parameters=[...]), the generated parameter schema includes both enum and minLength: 1.
For enum-constrained string parameters where all enum values are non-empty, minLength: 1 is redundant because enum already excludes "".
This adds schema noise and can cause some client generators to treat the extra constraint as meaningful.
To Reproduce
from rest_framework import serializers
from rest_framework.views import APIView
from drf_spectacular.utils import extend_schema
class MyParameterSerializer(serializers.Serializer):
sort = serializers.ChoiceField(
choices=["name", "display_name"],
required=False,
)
class MyView(APIView):
@extend_schema(parameters=[MyParameterSerializer])
def get(self, request):
...
Generated schema:
- name: sort
in: query
required: false
schema:
type: string
minLength: 1 # ← redundant; enum already excludes ""
enum:
- display_name
- name
The minLength: 1 originates from build_parameter_type in plumbing.py ~line 412:
if not allow_blank and schema['schema'].get('type') == 'string':
schema['schema']['minLength'] = schema['schema'].get('minLength', 1)
Expected behavior
When enum is present and all enum values are non-empty strings, minLength: 1 should be suppressed since the constraint is strictly redundant:
- name: sort
in: query
required: false
schema:
type: string
enum:
- display_name
- name
Plain CharField parameters (no enum) should continue to emit minLength: 1 as they do today — this is accurate for request-only parameters.
Suggested fix
A narrow, backward-compatible change in build_parameter_type:
if not allow_blank and schema['schema'].get('type') == 'string':
# Skip minLength when enum already constrains values and excludes empty strings
enum_values = schema['schema'].get('enum')
if not enum_values or '' in enum_values:
schema['schema']['minLength'] = schema['schema'].get('minLength', 1)
This only suppresses minLength when enum exists and all enum values are non-empty strings. All other string parameter behavior is unchanged.
For additional context, the component schema path in openapi.py (~line 1006) gates minLength behind ENFORCE_NON_BLANK_FIELDS and COMPONENT_SPLIT_REQUEST, though that distinction makes sense since component schemas can describe responses where DRF doesn't enforce allow_blank.
Happy to submit a PR if this approach seems reasonable.
Versions
- drf-spectacular 0.29.0
- Django 5.2+ (tested on 6.0.2)
- DRF 3.16.1
- Python 3.13
Describe the bug
When a ChoiceField is used as a query parameter via @extend_schema(parameters=[...]), the generated parameter schema includes both enum and minLength: 1.
For enum-constrained string parameters where all enum values are non-empty, minLength: 1 is redundant because enum already excludes "".
This adds schema noise and can cause some client generators to treat the extra constraint as meaningful.
To Reproduce
Generated schema:
The
minLength: 1originates frombuild_parameter_typeinplumbing.py~line 412:Expected behavior
When
enumis present and all enum values are non-empty strings,minLength: 1should be suppressed since the constraint is strictly redundant:Plain
CharFieldparameters (noenum) should continue to emitminLength: 1as they do today — this is accurate for request-only parameters.Suggested fix
A narrow, backward-compatible change in
build_parameter_type:This only suppresses
minLengthwhenenumexists and all enum values are non-empty strings. All other string parameter behavior is unchanged.For additional context, the component schema path in
openapi.py(~line 1006) gatesminLengthbehindENFORCE_NON_BLANK_FIELDSandCOMPONENT_SPLIT_REQUEST, though that distinction makes sense since component schemas can describe responses where DRF doesn't enforceallow_blank.Happy to submit a PR if this approach seems reasonable.
Versions