Creating config schema file for mutable data I have a custom module where I need to have a couple different types of configuration, both immutable and mutable. The immutable portion contains a feed URL for a couple different sites, so I have /my_module/config/install/my_module.settings.yml set up like this:

sites:
  site1:
    channel_url: 'http://www.site1.org/feed/channels'
  site2:
    channel_url: 'http://www.site2.com/feed/channels'
list_time: 24


That works fine, and I can read from it via $config-get();.

The second part of my settings involves mapping of tids between the two sites (used for importing video nodes from one site to another. My initial thought was to modify the settings like so:

sites:
  site1:
    channel_url: 'http://www.site1.org/feed/channels'
    mappings:
      1: 1
      2: 2
      3: 3
  site2:
    channel_url: 'http://www.site2.com/feed/channels'
    mappings:
      7: 7
      8: 8
      9: 9
list_time: 24


However, since this is mutable, it appears that this isn't allowed (based on the error messages I get when I try to run $config-&gt;set().

From what I'm finding, it looks like I need to have a separate schema config file for my mapping data. I'm still wading through docs, but if someone could verify if I'm correct in my thinking and maybe provide a sample of what my schema should look like, I'd appreciate it.

UPDATE: Reading through this change record, it appears that I can write to my settings file if I declare it in my form class in getEditableConfigNames(), which I've done:

protected function getEditableConfigNames() {
  return ['my_module.settings'];
}


It also appears that, according to the error message I get, I need to retrieve it with \Drupal\Core\Config\ConfigFactoryInterface::getEditable()

Drupal\Core\Config\ImmutableConfigException: Can not set values on immutable configuration my_module.settings:sites. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object in Drupal\Core\Config\ImmutableConfig-&gt;set() (line 27 of core/lib/Drupal/Core/Config/ImmutableConfig.php).


Just keep swimming....

UPDATE2: Base on @berdir's comment below, I'm showing what I have, since in my original question, I didn't state that I am already using the ConfigFormBase class:

class MyModuleAdminForm extends ConfigFormBase {

  /**
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'my_module_settings';
  }

  /**
   * {@inheritdoc}
   */
  public function buildform(array $form, FormStateInterface $form_state) {
    $form = array();
    $channels = array();

    // build form here

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}.
   */
  public function validateForm(array &amp;$form, FormStateInterface $form_state) {

  }

  protected function getEditableConfigNames() {
    return ['my_module.settings'];
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &amp;$form, FormStateInterface $form_state) {
    $values = $form_state-&gt;getValues();
    $config = $this-&gt;config('my_module:settings');

    foreach($values as $site =&gt; $mappings) {
      if (is_array($mappings)) {
        foreach ($mappings as $source_channel =&gt; $target_channel) {
          $config-&gt;set('sites',[$site =&gt; ['mappings' =&gt; [$source_channel =&gt; $target_channel]]]);
        }
      }
    }
     $config-&gt;save();

    parent::submitForm($form, $form_state);
  }
}


However, this still gives me the same error. Am I using $this->config() incorrectly? Or do I still need to use getEditable() somewhere?
Mutable or Immutable has nothing to do with config schema, that's something else.

getEditableConfigNames() only works if you actually implement \Drupal\Core\Form\ConfigFormBase and $this->config().

Otherwise you need to explicitly get the config.factory service or \Drupal::configFactory() and then call getEditable() on that, instead of get().