HumanSignal/label-studio · error · ValidationError

User filter values must be integer ids.

Error message

User filter values must be integer ids.

What it means

parse_user_filter_ids converts filter values into a deduplicated list of integer ids. Booleans, non-integer floats, and anything not coercible with int() raise ValidationError('User filter values must be integer ids.') — the parser is deliberately strict to keep ids clean.

Source

Thrown at label_studio/data_manager/managers.py:661

        return []
    if (
        isinstance(value, list)
        and not isinstance(value, ResolvedUserFilterIds)
        and len(value) > settings.DATA_MANAGER_LIST_FILTER_MAX_VALUES
    ):
        raise ValidationError(
            f'User filter list exceeds maximum size of {settings.DATA_MANAGER_LIST_FILTER_MAX_VALUES}.'
        )
    raw = value if isinstance(value, list) else [value]
    ids = []
    seen = set()
    for item in raw:
        try:
            if isinstance(item, bool) or (isinstance(item, float) and not item.is_integer()):
                raise ValueError
            user_id = int(item)
        except (TypeError, ValueError):
            raise ValidationError('User filter values must be integer ids.') from None
        if user_id not in seen:
            seen.add(user_id)
            ids.append(user_id)
    return ids


def _annotation_id(value):
    """Return an exact integer ID, accepting integer-valued Number representations only."""
    if isinstance(value, bool):
        return None
    if isinstance(value, int):
        return value
    try:
        number = Decimal(str(value).strip())
    except (AttributeError, InvalidOperation, ValueError):
        return None
    if not number.is_finite() or number != number.to_integral_value():
        return None

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Coerce each entry with int(str) or Number.parseInt and validate before sending
  2. Filter out booleans/null/undefined client-side
  3. Ensure ids originate from the API's numeric id fields, not labels or UUIDs
  4. Sanitize CSV/spreadsheet imports to numeric values

Example fix

// before
filter_value = ["1", true, 2.5]
// after
filter_value = [int(x) for x in raw if str(x).strip().lstrip('-').isdigit()]  # -> [1, 2]
Defensive patterns

Strategy: validation

Validate before calling

function toIdList(raw) {
  return raw.filter(x => typeof x !== 'boolean' && x !== null && x !== undefined)
            .map(x => Number(x))
            .filter(n => Number.isInteger(n) && !Number.isNaN(n));
}

Type guard

const isId = (x) => (typeof x === 'number' && Number.isInteger(x)) || (typeof x === 'string' && /^-?\d+$/.test(x.trim()));

Try / catch

try:
    add_user_filter(...)
except ValidationError as e:
    if 'must be integer ids' in str(e): sanitize_ids_and_retry(e)
    else: raise

Prevention

When it happens

Trigger: Values like '12abc', 1.5, true, null, or nested objects inside the filter's list/scalar value passed to add_user_filter or validate().

Common situations: JavaScript sending string ids with whitespace/symbols; spreadsheet exports yielding float ids (1.0 is OK, 1.5 is not); booleans leaking in from checkboxes; NaN/undefined serialized as strings.

Related errors


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