HumanSignal/label-studio · error · ValueError

Incorrect bool value "{value}". It should be one of [1, 0, t

Error message

Incorrect bool value "{value}". It should be one of [1, 0, true, false, yes, no]

What it means

cast_bool_from_str converts request string values to booleans, accepting only a fixed set of truthy ('true','yes','on','1') and falsy ('false','no','not','off','0') words (case-insensitive). Any other string raises ValueError with the allowed values listed. Non-string values pass through unchanged.

Source

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

import os
from typing import Callable, Optional, Sequence, TypeVar

from rest_framework.exceptions import ValidationError


def cast_bool_from_str(value):
    if isinstance(value, str):
        if value.lower() in ['true', 'yes', 'on', '1']:
            value = True
        elif value.lower() in ['false', 'no', 'not', 'off', '0']:
            value = False
        else:
            raise ValueError(f'Incorrect bool value "{value}". It should be one of [1, 0, true, false, yes, no]')
    return value


def bool_from_request(params, key, default):
    """Get boolean value from request GET, POST, etc

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

    try:
        if isinstance(value, str):
            value = cast_bool_from_str(value)
        return bool(int(value))
    except Exception as e:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Send one of the accepted values: 1, 0, true, false, yes, no (case-insensitive; 'on'/'off'/'not' also accepted).
  2. Sanitize/normalize the value on the client before sending, mapping your app's boolean vocabulary to these words.
  3. If parsing untrusted input, wrap the call in try/except ValueError and fall back to a default.
  4. Inspect the request param that carries this value — the message includes the offending string.

Example fix

// before
GET /api/projects/?was_enabled=yes&include=maybe
// after — only accepted words for boolean params
GET /api/projects/?was_enabled=yes&include=true
Defensive patterns

Strategy: validation

Validate before calling

ACCEPTED = {'true','yes','on','1','false','no','not','off','0'}
def is_bool_str(v) -> bool:
    return not isinstance(v, str) or v.lower() in ACCEPTED

Type guard

def parse_bool(value):
    if isinstance(value, str):
        if value.lower() in ('true','yes','on','1'): return True
        if value.lower() in ('false','no','not','off','0'): return False
        return None  # invalid
    return bool(value)

Try / catch

try:
    flag = bool_from_request(params, 'include', False)
except ValueError as e:
    return Response({'error': str(e)}, status=400)

Prevention

When it happens

Trigger: Passing a query/body parameter parsed by bool_from_request or filters (cast_value, add_result_filter, add_user_filter, annotation_id_filter_q, normalize_persisted_user_filter) whose value is a string other than the accepted words — e.g. 'True ' is fine (lowered) but 'enabled', 't', '2', or 'oui' raise.

Common situations: Frontends sending 'enabled'/'disabled' or localized booleans; users typing filters in the URL like ?aggregation=true-ish; API consumers sending 'Y'/'N'; accidentally sending a word where a boolean is expected.

Related errors


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