apache/superset · error · ValidationError

Duplicate folder name: {name}

Error message

Duplicate folder name: {name}

What it means

Raised by validate_folders() when two folders share the same fully-qualified name — i.e. the same name among siblings (same parent path). Duplicate names are allowed only in different branches; seen_fqns keys on tuple(path + [name]) so the same name under the same parent collides.

Source

Thrown at superset/commands/dataset/update.py:462

    queue: list[tuple[FolderSchema, list[UUID]]] = [(folder, []) for folder in folders]
    seen_uuids = set()
    seen_fqns = set()  # fully qualified folder names
    while queue:
        obj, path = queue.pop(0)
        uuid, name = obj["uuid"], obj.get("name")

        if uuid in path:
            raise ValidationError(f"Cycle detected: {uuid} appears in its ancestry")

        if uuid in seen_uuids:
            raise ValidationError(f"Duplicate UUID in folder structure: {uuid}")
        seen_uuids.add(uuid)

        # folders can have duplicate name as long as they're not siblings
        if name:
            fqn = tuple(path + [name])
            if name and fqn in seen_fqns:
                raise ValidationError(f"Duplicate folder name: {name}")
            seen_fqns.add(fqn)

            # Allow default folders (by UUID) to use reserved names
            if (
                name.lower() in {"metrics", "columns"}
                and str(uuid) not in DEFAULT_FOLDER_UUIDS
            ):
                raise ValidationError(f"Folder cannot have name '{name}'")

        # check if metric/column UUID exists (skip default folders)
        elif (
            not name
            and uuid not in valid_uuids
            and str(uuid) not in DEFAULT_FOLDER_UUIDS
        ):
            raise ValidationError(f"Invalid UUID: {uuid}")

        # traverse children

View on GitHub (pinned to f4587218dd)

Solutions

  1. Rename one of the colliding siblings (the message names it) so names are unique within the parent.
  2. Or move one folder under a different parent where the name is free.
  3. Check the fqn (full path) semantics: only same-parent duplicates are rejected.

Example fix

# before
[{name: "Sales", children: [{name: "Q1"}, {name: "Q1"}]}]
# after
[{name: "Sales", children: [{name: "Q1"}, {name: "Q1 (archive)"]}]}
Defensive patterns

Strategy: validation

Validate before calling

def sibling_name_clash(folders):
    stack = [(f, ()) for f in folders]
    seen = set()
    while stack:
        node, path = stack.pop()
        if (name := node.get("name")):
            fqn = path + (name,)
            if fqn in seen:
                return name
            seen.add(fqn)
            path = fqn
        stack.extend((c, path) for c in node.get("children", []))
    return None

assert sibling_name_clash(folders) is None

Prevention

When it happens

Trigger: PUT /api/v1/dataset/{id} with two sibling folders both named e.g. 'Sales' under the same parent, where at least one carries an explicit name.

Common situations: Renaming a folder to match its sibling. Merging folder trees where both sources had a child with the same name under the equivalent parent.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/fe7fc0a3e3fe527a. Report an issue: GitHub.