Incorrect "missing schema" error for widget settings, if widget has the same id as formatter / field type

Created on 2 May 2024, 8 months ago
Updated 7 May 2024, 8 months ago

Problem/Motivation

Currently, in the Micon module, we get a schema error for the "string_micon" widget setting "packages" through config_inspector:

missing schema => 'packages' is not a supported key.

"packages" is defined as a sequence, which uses "checkboxes" as their fronted form element:
Form Element:

    $element['packages'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Icon Packages'),
      '#default_value' => $this->getSetting('packages'),
      '#description' => $this->t('The icon packages that should be made available in this field. If no packages are selected, all will be made available.'),
      '#options' => Micon::loadActiveLabels(),
    ];

Schema definition:

field.widget.settings.micon_string:
  type: mapping
  label: 'Micon String widget settings'
  mapping:
    packages:
      type: sequence
      label: 'Packages'
      sequence:
        type: string
        label: 'Micon ID'

This schema error seems to be incorrect, as the schema definition is clearly there. Also:

  1. The module provides config test modules, which come with node form_displays with the "packages" widget settings set. These are getting installed through an implemented GenericTest class extending "GenericModuleTestBase" and do NOT throw any schema errors ("$strictConfigSchema" is not manually set to FALSE).
  2. We are using the EXACT SAME "packages" setting for a widget in our "micon_link" submodule with the EXACT SAME schema, but there we do not get any schema errors from config inspector nor through the dedicated config tests.
  3. The same checkboxes form element + schema combination is used in the "book" core module. See here and here.

Meaning the schema error thrown by config_inspector is probably incorrect, as the core schema validation (executed through tests) seems to have no problem with it.

So what is the cause of this?

The main "micon" module provides a FieldType, FieldWidget and FieldFormatter with the exact same ID ("string_micon"). This is far from optimal, but simply what the original maintainer implemented.

Through 📌 Adjust main module's widget / formatter / field type ids Active , I changed the widget ID, reinstalled the module, created a field with the widget and widget settings applied and suddenly, the schema error thrown by config inspector was gone. So it seems like config inspector's schema error scope is too broad?

Steps to reproduce

  • Install the latest version of Micon .
  • Create an Icon field on a node bundle (e.g. article).
  • Go to "Manage form display" => Icon field, select "Font Awesome" from the widget settings and save.
  • Go to the config_inspector page ("/admin/reports/config-inspector") and only show errors. There should be 1 schema error on the node bundles form display (e.g. core.entity_form_display.node.article.default).
  • The error says, that it has no schema definition for "content.field_icon.settings.packages".

Now:

  • Delete the icon field
  • Apply the MR diff from here.
  • Reinstall the module.
  • Create an Icon field on a node bundle (e.g. article).
  • Go to "Manage form display" => Icon field, select "Font Awesome" from the widget settings and save.
  • Go to the config_inspector page ("/admin/reports/config-inspector") and only show errors. => no errors are left.

Proposed resolution

Fix the widget settings schema validation when identical ids are used on other field plugins.

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Active

Version

2.1

Component

Code

Created by

🇩🇪Germany Grevil

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Grevil
  • Status changed to Postponed: needs info 8 months ago
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    I agree the schema looks correct. 🤔

    However, the Config Inspector module does not contain the string missing schema anywhere. So it must come from \Drupal\Core\Config\Schema\SchemaCheckTrait::checkValue() which contains:

        if ($element instanceof Undefined) {
          return [$error_key => 'missing schema'];
        }
    
    1. Can you please provide a config export of the config that triggers this error? Just paste the YAML here :) I bet that's where the problem is: the schema looks fine, but probably the config data itself is not.
    2. You can do what I'd do too: put a breakpoint on the quoted line above and re-trigger the error, then observe how you get to that point!
  • 🇩🇪Germany Grevil

    Sure thing!

    Here is the output, which LGTM ("field_icon.settings.packages" throws the error: "'packages' is not a supported key."):

    uuid: bef6d86a-4328-4e29-a0a9-6f83b1de96d7
    langcode: en
    status: true
    dependencies:
      config:
        - field.field.node.article.body
        - field.field.node.article.comment
        - field.field.node.article.field_icon
        - field.field.node.article.field_image
        - field.field.node.article.field_tags
        - image.style.thumbnail
        - node.type.article
      module:
        - comment
        - image
        - micon
        - path
        - text
    _core:
      default_config_hash: ewbd6G2uX456-bgwseM2Q-KQG3RkASoyHmTh-XR3oLU
    id: node.article.default
    targetEntityType: node
    bundle: article
    mode: default
    content:
      body:
        type: text_textarea_with_summary
        weight: 2
        region: content
        settings:
          rows: 9
          summary_rows: 3
          placeholder: ''
          show_summary: false
        third_party_settings: {  }
      comment:
        type: comment_default
        weight: 20
        region: content
        settings: {  }
        third_party_settings: {  }
      created:
        type: datetime_timestamp
        weight: 10
        region: content
        settings: {  }
        third_party_settings: {  }
      field_icon:
        type: string_micon
        weight: 121
        region: content
        settings:
          packages:
            fa: fa
        third_party_settings: {  }
      field_image:
        type: image_image
        weight: 1
        region: content
        settings:
          progress_indicator: throbber
          preview_image_style: thumbnail
        third_party_settings: {  }
      field_tags:
        type: entity_reference_autocomplete_tags
        weight: 3
        region: content
        settings:
          match_operator: CONTAINS
          match_limit: 10
          size: 60
          placeholder: ''
        third_party_settings: {  }
      path:
        type: path
        weight: 30
        region: content
        settings: {  }
        third_party_settings: {  }
      promote:
        type: boolean_checkbox
        weight: 15
        region: content
        settings:
          display_label: true
        third_party_settings: {  }
      status:
        type: boolean_checkbox
        weight: 120
        region: content
        settings:
          display_label: true
        third_party_settings: {  }
      sticky:
        type: boolean_checkbox
        weight: 16
        region: content
        settings:
          display_label: true
        third_party_settings: {  }
      title:
        type: string_textfield
        weight: 0
        region: content
        settings:
          size: 60
          placeholder: ''
        third_party_settings: {  }
      uid:
        type: entity_reference_autocomplete
        weight: 5
        region: content
        settings:
          match_operator: CONTAINS
          match_limit: 10
          size: 60
          placeholder: ''
        third_party_settings: {  }
    hidden: {  }
    
  • 🇩🇪Germany Grevil

    You can do what I'd do too: put a breakpoint on the quoted line above and re-trigger the error, then observe how you get to that point!

    Can't seem to get into the correct loop iteration without "steping over" a hundred times.

    And this workaround:

    Doesn't seem to trigger xdebug for some reason...

  • Status changed to Active 8 months ago
  • 🇩🇪Germany Grevil

    Ok, no idea what I was doing there yesterday...

    So I put a breakpoint at the exact location you pinpointed me to. But it looks fine to me!

    The key is correct: $key = "content.field_icon.settings.packages"

    And the $this->schema variable also seems to hold the correct values:

    and the schema definition looks good as well:

    I really doubt, that the implementation of Drupal\Core\Config\Schema\ArrayElement::get(), which is inherited and used by the

    $element = $this->schema->get($key);

    call.
    But I don't see anything else, that could lead to this? Am I missing something?

Production build 0.71.5 2024