{"record":{"id":"f5b7dced6fddcec6","repo":"HumanSignal/label-studio","slug":"label-config-contains-non-unique-names","errorCode":null,"errorMessage":"Label config contains non-unique names: ","messagePattern":"Label config contains non-unique names: ","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"label_studio/core/label_config.py","lineNumber":127,"sourceCode":"    try:\n        config, cleaned_config_string = parse_config_to_json(config_string)\n        jsonschema.validate(config, _LABEL_CONFIG_SCHEMA_DATA)\n    except (etree.ParseError, ValueError) as exc:\n        raise ValidationError(str(exc))\n    except jsonschema.exceptions.ValidationError as exc:\n        # jsonschema4 validation error now includes all errors from \"anyOf\" subschemas\n        # check https://python-jsonschema.readthedocs.io/en/latest/errors/#jsonschema.exceptions.ValidationError.context\n        # we pick the first failed schema and show only its error message\n        error_message = exc.context[0].message if len(exc.context) else exc.message\n        error_message = 'Validation failed on {}: {}'.format(\n            '/'.join(map(str, exc.path)), error_message.replace('@', '')\n        )\n        raise ValidationError(error_message)\n\n    # unique names in config # FIXME: 'name =' (with spaces) won't work\n    all_names = re.findall(r'(?:^|[^\\w])name=\"([^\"]*)\"', cleaned_config_string)\n    if len(set(all_names)) != len(all_names):\n        raise ValidationError('Label config contains non-unique names: ' + ', '.join(all_names))\n\n    # toName points to existent name\n    names = set(all_names)\n    toNames = re.findall(r'toName=\"([^\"]*)\"', cleaned_config_string)\n    for toName_ in toNames:\n        for toName in toName_.split(','):\n            if toName not in names:\n                raise ValidationError(f'toName=\"{toName}\" not found in names: {sorted(names)}')\n\n    # Tag attribute validation (e.g. Video playback speed) via SDK\n    try:\n        li = LabelInterface(config_string)\n        if hasattr(li, '_tag_attribute_validation'):\n            li._tag_attribute_validation()\n    except LabelStudioValidationErrorSentryIgnored as exc:\n        raise ValidationError(str(exc))\n\n","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/core/label_config.py#L109-L145","documentation":"Label config tag names (name=\"...\") must be unique. After schema validation, validate_label_config collects all name=\"...\" values via regex and raises this ValidationError if the set of names is smaller than the list (duplicates exist). Note the FIXME: names written with spaces like 'name =' are not matched.","triggerScenarios":"A label config containing two or more tags with the same name=\"...\" value, passed to validate_label_config (e.g. saving project labeling config via API or UI).","commonSituations":"Duplicating a tag block (e.g. two <Text name=\"text\"> or two <Choices name=\"sentiment\">) when composing complex configs; merging configs from templates without renaming.","solutions":["Find duplicate names in your config (search name=\" occurrences) and rename all but one uniquely.","Use descriptive unique names per tag, e.g. name=\"text1\", name=\"text2\".","Remember to update corresponding toName=\"...\" references after renaming.","Note: 'name =' with spaces before '=' isn't detected by this check — keep attribute syntax as name=\"value\"."],"exampleFix":"<!-- before -->\n<Text name=\"text\" value=\"$article\"/>\n<Text name=\"text\" value=\"$summary\"/>\n<!-- after -->\n<Text name=\"article\" value=\"$article\"/>\n<Text name=\"summary\" value=\"$summary\"/>","handlingStrategy":"validation","validationCode":"import re\ndefens_names = re.findall(r'(?:^|[^\\w])name=\"([^\"]*)\"', config)\ndups = {n for n in defens_names if defens_names.count(n) > 1}\nif dups:\n    raise ValueError(f'Duplicate tag names: {dups}')","typeGuard":null,"tryCatchPattern":"try:\n    validate_label_config(config)\nexcept ValidationError as e:\n    if 'non-unique names' in str(e):\n        return Response({'error': str(e), 'hint': 'Rename duplicate tag name attributes'}, status=400)\n    raise","preventionTips":["Keep a naming convention per tag type (e.g. choices1, choices2).","Search the config for name=\" before submitting and eyeball for repeats.","When copying tag blocks, rename the copy immediately.","Automate a duplicate-name check in your config linting."],"tags":["validation","label-config","xml"],"backgroundTag":"duplicate-identifier","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}