HumanSignal/label-studio · error · ValidationError
replace(old_value, new_value) requires two arguments.
Error message
replace(old_value, new_value) requires two arguments.
What it means
The DataManager 'replace' expression substitutes occurrences of old_value with new_value in a column. add_expression enforces exactly two JSON-encoded arguments and raises this ValidationError when len(args) != 2.
Source
Thrown at label_studio/data_manager/actions/data_columns.py:310
elif command == 'sample':
if args:
raise ValidationError({'value': 'sample() does not accept arguments.'})
sample_values = iter(random.sample(range(0, size), size))
elif command == 'random':
if len(args) != 2:
raise ValidationError({'value': 'random(min, max) requires two arguments.'})
minimum, maximum = int(args[0]), int(args[1])
elif command == 'choices':
if not 0 < len(args) < 3:
raise ValidationError({'value': 'choices(values:list, weights:list) requires one or two arguments.'})
weights = json.loads(args[1]) if len(args) == 2 else None
choices = json.loads(args[0])
elif command == 'replace':
if len(args) != 2:
raise ValidationError({'value': 'replace(old_value, new_value) requires two arguments.'})
old_value, new_value = json.loads(args[0]), json.loads(args[1])
else:
raise ValidationError('Undefined expression, you can use: ' + add_data_field_examples)
offset = 0
task_iterator = iterate_queryset(queryset.only('id', 'data'), chunk_size=settings.UPDATE_COLUMN_BATCH_SIZE)
for task_batch in batched_iterator(task_iterator, settings.UPDATE_COLUMN_BATCH_SIZE):
if command == 'range':
for index, task in enumerate(task_batch):
task.data[value_name] = start + offset + index
elif command == 'sample':
for task in task_batch:
task.data[value_name] = next(sample_values)
elif command == 'random':
for task in task_batch:
task.data[value_name] = random.randint(minimum, maximum)
elif command == 'choices':View on GitHub (pinned to 0b49e9b539)
Solutions
- Provide exactly two JSON-encoded arguments: {"args": ["\"foo\"", "\"bar\""]}
- To replace with empty string, pass the JSON string "" as new_value rather than omitting the argument
- Ensure old_value and new_value round-trip through json.loads (quoted strings, numbers, etc.)
Example fix
// before
{"command": "replace", "args": ["\"foo\""]}
// after
{"command": "replace", "args": ["\"foo\"", "\"bar\""]} Defensive patterns
Strategy: validation
Validate before calling
if (expr.command === 'replace' && (!Array.isArray(expr.args) || expr.args.length !== 2)) {
throw new Error('replace requires exactly [old_value, new_value]');
} Type guard
function isValidReplace(e) { return e.command === 'replace' && Array.isArray(e.args) && e.args.length === 2; } Try / catch
try {
await dm.addAction({id: 'add_data_field', expression: expr});
} catch (e) {
if (String(e).includes('replace(old_value, new_value) requires two')) {
expr.args = [JSON.stringify(oldV), JSON.stringify(newV)];
return retry();
}
throw e;
} Prevention
- Always JSON-stringify both old_value and new_value args
- For deletion-like replaces pass "" as new_value instead of omitting it
- Centralize payload construction so arg counts stay consistent
When it happens
Trigger: Calling the add-data-field action with {"command": "replace", "args": ["foo"]} (missing new value), args: [], or three+ args via the column mutation action.
Common situations: Developers pass only the old value assuming a delete-replace; arguments not JSON-encoded (plain strings like foo instead of "foo") so they are dropped or malformed; UI sending empty optional fields.
Related errors
- sample() does not accept arguments.
- random(min, max) requires two arguments.
- choices(values:list, weights:list) requires one or two argum
- Undefined expression, you can use: {add_data_field_examples}
- Can't find '{action_id}' in registered actions
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/f07a8fe9ae9290ff.
Report an issue: GitHub.