Как API конфигурации говорит, что каждый модуль должен определить свою схему конфигурации в файлах в каталоге config/schema в каталоге модуля верхнего уровня. Это используется ядром Drupal для проверки файла конфигурации и проверки того, что он не поврежден.
Например, модуль Book использует следующую схему для своего объекта конфигурации (core/modules/book/config/schema/book.schema.yml).
# Схема конфигурационных файлов книжного модуля.
книга.настройки:
  тип: config_object
  label: 'Настройки книги'
  сопоставление:
    разрешенные_типы:
      тип: последовательность
      label: 'Типы контента, разрешенные в планах книг'
      последовательность:
        тип: строка
        label: 'Тип контента'
    блокировать:
      тип: отображение
      метка: «Заблокировать»
      сопоставление:
        навигация:
          тип: отображение
          этикетка: 'Навигация'
          сопоставление:
            Режим:
              тип: строка
              метка: 'Режим'
    дочерний_тип:
      тип: строка
      label: 'Тип контента для дочерних страниц'
block.settings.book_navigation:
  тип: block_settings
  label: 'Блок навигации по книге'
  сопоставление:
    блок_режим:
      тип: строка
      label: 'Блокировать режим отображения'
Это отличается от его файла конфигурации, который находится в core/modules/book/config/installbook.settings.yml.
разрешенные_типы:
  - книга
блокировать:
  навигация:
    режим: «все страницы»
child_type: книга
Код, вызывающий это исключение, содержится в ConfigSchemaChecker класс, используемый для реализации подписчика событий, который вызывается при сохранении объекта конфигурации.
  общедоступная функция onConfigSave (ConfigCrudEvent $event) {
    // Проверять конфигурацию, только если она находится в коллекции по умолчанию. Другой
    // коллекции могут иметь неполную конфигурацию (например, язык
    // только переопределения). Они недействительны сами по себе.
    $saved_config = $event->getConfig();
    if ($saved_config->getStorage()->getCollectionName() != StorageInterface::DEFAULT_COLLECTION) {
      возвращаться;
    }
    $name = $saved_config->getName();
    $data = $saved_config->get();
    $checksum = Crypt::hashBase64(serialize($data));
    if (!in_array($name, $this->exclude) && !isset($this->checked[$name . ':' . $checksum])) {
      $this->checked[$name . ':' . $контрольная сумма] = ИСТИНА;
      $errors = $this->checkConfigSchema($this->typedManager, $name, $data);
      если ($ ошибки === ЛОЖЬ) {
        выбросить новое исключение SchemaIncompleteException("Нет схемы для {$name}");
      }
      elseif (is_array($errors)) {
        $text_errors = [];
        foreach ($errors as $key => $error) {
          $text_errors[] = new FormattableMarkup('@key @error', [
            '@ключ' => $ключ,
            '@error' => $ошибка,
          ]);
        }
        throw new SchemaIncompleteException("Ошибки схемы для {$name} со следующими ошибками: " .implode(', ', $text_errors));
      }
    }
  }