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 float.

What it means

float_from_request raises this when the value is neither a string, float, nor int — i.e. an unsupported type like list, dict, or bool. It signals a type mismatch rather than a parse failure, distinct from error 11 which fires on unparseable strings.

Source

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

    :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)
        except ValueError:
            raise ValidationError({key: f'Incorrect value in key "{key}" = "{value}". It should be digit string.'})
    # float
    elif isinstance(value, float) or isinstance(value, int):
        return float(value)
    # other
    else:
        raise ValidationError(
            {key: f'Incorrect value type in key "{key}" = "{value}". It should be digit string or float.'}
        )


def list_of_strings_from_request(params, key, default):
    """Get list of strings 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)
    if value is None:
        return
    splitters = (',', ';', '|')
    # str
    if isinstance(value, str):

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Send the value once as a single scalar (string or number) instead of repeated/array form.
  2. Client-side: ensure the param is a str/int/float, e.g. str(float(x)) before sending.
  3. Check for accidental JSON nesting of the key in the request body.
  4. Catch ValidationError in the endpoint and return a 400 identifying the key.

Example fix

// before
GET /api/annotations?score=0.5&score=0.6  (parsed as list)

// after
GET /api/annotations?score=0.5
Defensive patterns

Strategy: validation

Validate before calling

def ensure_scalar_number(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, float)):
        raise ValueError(f'{key} must be a scalar number')
    return float(value)

Type guard

def is_scalar_number(value) -> bool:
    return isinstance(value, (str, int, float))

Try / catch

try:
    score = float_from_request(request.GET, 'score', 0.0)
except ValidationError as e:
    return Response({'detail': 'score must be a single scalar value'}, status=400)

Prevention

When it happens

Trigger: Calling an endpoint that uses float_from_request with a param that Django deserialized into a list (repeated query keys like `?x=1&x=2`), a dict (JSON body nested object), or another non-scalar type.

Common situations: Frontends sending arrays via repeated query params; JSON bodies passing nested objects where a scalar number is expected; accidentally passing bool values from typed clients.

Related errors


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