HumanSignal/label-studio · error · DataManagerException
selectedItems must be dict: {"all": [true|false], "excluded
Error message
selectedItems must be dict: {"all": [true|false], "excluded | included": [...task_ids...]}. Found type: {type(selected)} with value: {selected} What it means
get_prepare_params requires selectedItems to be a dict (or a JSON string that parses to the expected shape). If the value is neither a string nor a dict — e.g. a list, number, or bool — it raises DataManagerException stating the required dict shape and the offending type/value.
Source
Thrown at label_studio/data_manager/functions.py:316
# data payload from body
else:
data = request.data
selected = data.get('selectedItems', {'all': True, 'excluded': []})
if not isinstance(selected, dict):
if isinstance(selected, str):
# try to parse JSON string
try:
selected = json.loads(selected)
except Exception as e:
logger.error(f'Error parsing selectedItems: {e}')
raise DataManagerException(
'selectedItems must be JSON encoded string for dict: {"all": [true|false], '
'"excluded | included": [...task_ids...]}. '
f'Found: {selected}'
)
else:
raise DataManagerException(
'selectedItems must be dict: {"all": [true|false], '
'"excluded | included": [...task_ids...]}. '
f'Found type: {type(selected)} with value: {selected}'
)
filters = data.get('filters', None)
ordering = data.get('ordering', [])
prepare_params = PrepareParams(
project=project.id, selectedItems=selected, data=data, filters=filters, ordering=ordering, request=request
)
return prepare_params
def get_prepared_queryset(request, project):
prepare_params = get_prepare_params(request, project)
queryset = Task.prepared.only_filtered(prepare_params=prepare_params)
return queryset
View on GitHub (pinned to 0b49e9b539)
Solutions
- Wrap the ids: send {"all": false, "included": [ids]} or {"all": true, "excluded": [ids]}`
- Ensure the client serializes an object, not an array, for selectedItems
- Check the API version/docs for the expected selectedItems schema
- Add client-side validation that typeof selectedItems === 'object' && !Array.isArray(...)
Example fix
// before
{"selectedItems": [12, 34]}
// after
{"selectedItems": {"all": false, "included": [12, 34]}} Defensive patterns
Strategy: type-guard
Validate before calling
const sel = payload.selectedItems;
if (sel === null || typeof sel !== 'object' || Array.isArray(sel)) throw new Error('selectedItems must be {"all":bool,"included|excluded":[ids]}'); Type guard
const isSelectedItemsDict = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && typeof v.all === 'boolean';
Try / catch
try { await submit(payload); } catch (e) { if (/selectedItems must be dict/.test(e.message)) { payload.selectedItems = { all: false, included: payload.selectedItems }; await submit(payload); } else { throw e; } } Prevention
- Always wrap ids in the {all, included|excluded} envelope
- Reject arrays at the form-serialization layer
- Keep client types aligned with the current API schema
- Unit-test request builders against the documented shape
When it happens
Trigger: Passing selectedItems as a bare list [1,2], an integer id, true/false, or null directly in the request body instead of the wrapper object {"all":bool,"excluded|included":[ids]}.
Common situations: Frontend code sending the raw selected-ids array; forgetting to wrap ids in the all/excluded/included envelope; schema drift between an older API version (plain id list) and the current one.
Related errors
- selectedItems must be JSON encoded string for dict: {"all":
- "file_upload_ids" parameter must be a list of integers
- sample() does not accept arguments.
- random(min, max) requires two arguments.
- choices(values:list, weights:list) requires one or two argum
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/902e02a1e3901b1d.
Report an issue: GitHub.