HumanSignal/label-studio · error · ValidationError

Incorrect value type in key "{key}" = "{value}". It should b

Error message

Incorrect value type in key "{key}" = "{value}". It should be digit string or integer.

What it means

int_from_request validates that a request parameter (GET/POST) identified by `key` is an integer or a digit-only string. If the value is any other type (e.g. list, dict, bool, float), it raises Django's ValidationError. This guards request-param parsing paths (pagination, task ops) against type confusion.

Source

Thrown at label_studio/core/utils/params.py:59

    :param default: default value
    :return: int
    """
    value = params.get(key, default)

    # str
    if isinstance(value, str):
        try:
            return int(value)
        except ValueError:
            raise ValidationError({key: f'Incorrect value in key "{key}" = "{value}". It should be digit string.'})
        except Exception as e:
            raise ValidationError({key: str(e)})
    # int
    elif isinstance(value, int):
        return value
    # other
    else:
        raise ValidationError(
            {key: f'Incorrect value type in key "{key}" = "{value}". It should be digit string or integer.'}
        )


def float_from_request(params, key, default):
    """Get float from request GET, POST, etc

    :param params: dict POST, GET, etc
    :param key: key to find
    :param default: default value
    :return: float
    """
    value = params.get(key, default)

    # str
    if isinstance(value, str):
        try:
            return float(value)

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Inspect the request and make sure the offending `key` param is sent once, as a plain digit string or integer (e.g. `page=3`).
  2. Client-side: convert the value with str(int(x)) before sending instead of passing floats/lists/bools.
  3. If a float is legitimately needed, use the float_from_request helper endpoint behavior instead of int parsing.
  4. Catch the raised ValidationError in the endpoint and return a 400 with the field key so the client can correct it.

Example fix

// before
curl '/api/tasks?page=1.5'

// after
curl '/api/tasks?page=1'
Defensive patterns

Strategy: validation

Validate before calling

def ensure_int_param(params, key):
    value = params.get(key)
    if isinstance(value, list):
        value = value[0] if len(value) == 1 else None
    if not isinstance(value, (str, int)) or (isinstance(value, str) and not value.isdigit()):
        raise ValueError(f'{key} must be a digit string or integer')
    return int(value)

Type guard

def is_int_like(value) -> bool:
    return isinstance(value, int) or (isinstance(value, str) and value.isdigit())

Try / catch

from rest_framework.exceptions import ValidationError
try:
    page = int_from_request(request.GET, 'page', 1)
except ValidationError as e:
    return Response({'detail': 'invalid integer param', 'errors': e.detail}, status=400)

Prevention

When it happens

Trigger: Calling an endpoint that uses int_from_request (e.g. paginators, get/post handlers like get_prepare_params) with a query/body param whose value is neither a str nor int — e.g. passing a float like 1.5, a list, or a nested object as the parameter.

Common situations: API clients sending `page=1.5` or JSON-typed values in query params; frontends sending arrays for repeated keys (`?page=1&page=2`) which Django parses into a list; automated scripts passing Python objects instead of scalar strings.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/cc349e98c33baad9. Report an issue: GitHub.