Skip to content

BlockKit 2 fails to validate StaticSelect initial_option values with grouped options #130

Description

@nickovs

Slack supports StaticSelect menus with grouped options, so that you can separate the options into related sets. It can also support specifying an initially selected option. Slack lets you do both at the same time. BlockKit v1 let you do both at the same time. BlockKit v2 fails when you try to do this while validating the option selections, raising the error:

blockkit.core.ComponentValidationError: Component 'StaticSelect': 'initial_option' has items that aren't present in the 'option_groups' 

The problem seems to stem from the use of Within validators attached to the StaticSelect class (the MultiStaticSelect has the same issue). The value for the initial_option is a single option (for initial_options for the multi-select it's a flat list of options) and you are comparing it to a list of groups, not a list of options.

The fix should be in the Within validator. When the target field contains OptionGroup objects, it should collect the options from within them and check if the initial value is a subset of the flattened set of values within the groups, rather than comparing against the groups themselves (which will always fail).

blockkit_bug_demo.py

Activity

  1. nickovs commented on Apr 22, 2026

    @nickovs
    Author

    Inserting something like this into the middle of `Within.validate() should do the trick:

              # If the target contains OptionGroups, flatten to the                                                                                                                                                    
              # options within them                                                                                                                                                                                    
              flattened = []                                                                                                                                                                                           
              for item in target_value:                                                                                                                                                                                
                  if isinstance(item, OptionGroup):                                                                                                                                                                    
                      group_opts = item._get_field_value("options")                                                                                                                                                    
                      if group_opts:                                                                                                                                                                                   
                          flattened.extend(group_opts)                                                                                                                                                                 
                  else:                                                                                                                                                                                                
                      flattened.append(item)                                                                                                                                                                           
              target_value = flattened                                                                                                                                                                                 
  2. nickovs commented on Apr 22, 2026

    @nickovs
    Author

    PR #131 is a fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions