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 NoneView on GitHub (pinned to 0b49e9b539)
Solutions
- Coerce each entry with int(str) or Number.parseInt and validate before sending
- Filter out booleans/null/undefined client-side
- Ensure ids originate from the API's numeric id fields, not labels or UUIDs
- 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
- Source ids only from numeric API fields, never labels or display text
- Strip whitespace and parse with Number.parseInt on the client
- Exclude booleans/null from checkbox-driven selections
- Sanitize spreadsheet/CSV values to integers at import
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
- Filter value must be a list for `is any of` / `is none of`.
- List-valued user filters support only these operators: {allo
- User filter "{field_name}" does not support operator "{opera
- `is any of` / `is none of` support Task ID, Inner ID, annota
- User filter list exceeds maximum size of {settings.DATA_MANA
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/6a6c9f3fa1819e0f.
Report an issue: GitHub.