HumanSignal/label-studio · error · ValidationError

Expression must use the form command(arguments).

Error message

Expression must use the form command(arguments).

What it means

add_expression validates that an Expression column value has the shape command(arguments): it must contain '(' and end with ')'. Otherwise ValidationError {'value': 'Expression must use the form command(arguments).'} is raised. Expressions like 'range' or 'sample' without parentheses are invalid.

Source

Thrown at label_studio/data_manager/actions/data_columns.py:275

    while start != end:
        end = start + params[start:].find(']') + 1
        params = params[0:start] + params[start:end].replace(',', ';') + params[end:]
        start = end + params[end:].find('[') + 1
    return params


add_data_field_examples = (
    'range(2) or '
    'sample() or '
    'random(<min_int>, <max_int>) or '
    'choices(["<value1>", "<value2>", ...], [<weight1>, <weight2>, ...]) or '
    'replace("old-string", "new-string")'
)


def add_expression(queryset, size, value, value_name):
    if '(' not in value or not value.endswith(')'):
        raise ValidationError({'value': 'Expression must use the form command(arguments).'})
    command, args = value.split('(', 1)
    if not command:
        raise ValidationError({'value': 'Expression command is required.'})
    args = process_arrays(args)
    args = args.replace(')', '').split(',')
    args = [] if len(args) == 1 and args[0] == '' else args
    for i, arg in enumerate(args):
        args[i] = arg.replace(';', ',').replace("'", '"')

    sample_values = None

    if command == 'range':
        if len(args) != 1:
            raise ValidationError({'value': 'range(start:int) requires one start argument.'})
        start = int(args[0])

    elif command == 'sample':
        if args:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Wrap the expression in command(args) form, e.g. 'range(10)' or 'sample()'.
  2. Ensure the value ends with ')' and contains at least one '('.
  3. Fix the client to append parentheses when only a command name is given.

Example fix

// before
value = 'range'
// after
value = 'range(10)'
Defensive patterns

Strategy: validation

Validate before calling

import re
expr = request_data.get('value', '')
if request_data.get('value_type') == 'Expression':
    assert '(' in expr and expr.endswith(')'), 'expression must be command(arguments)'

Type guard

def is_well_formed_expression(value):
    return isinstance(value, str) and '(' in value and value.endswith(')')

Try / catch

from rest_framework.exceptions import ValidationError
try:
    add_data_field(project, qs, request=request)
except ValidationError as e:
    if 'Expression must use the form' in str(e):
        suggest_command_template()

Prevention

When it happens

Trigger: Submitting value_type 'Expression' with value like 'range' (no parentheses), 'range(5' (missing closing paren), or 'x(' with nothing after.

Common situations: User typing just the command name in the dialog form; copy-paste losing the trailing ')'; templates showing range(start:int) copied verbatim.

Related errors


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