03 · TypeError in ComponentInputsMapping for config component trees with JSON-encoded inputs (breaks 5 Drupal CMS site templates)¶
| Project | Canvas |
| Component | Config management |
| Category | Bug report |
| Priority | Critical |
| Status | Reported upstream as #3592152 |
Problem/Motivation¶
Five Drupal CMS site templates cannot be installed at all – in any language:
- Archimedes (Zoocha)
- Healthcare (Kanopi)
- Pulse (QED42)
- CareSphere and Convene (OpenSense Labs)
The installation stops with:
TypeError: Drupal\canvas\Plugin\DataType\ComponentInputs::resolveConfigSchemaMapping(): Argument #3 ($actual_inputs) must be of type array, string given, called in canvas/src/Config/Schema/ComponentInputsMapping.php on line 54
All five ship Canvas configuration (canvas.content_template.*, canvas.page_region.*) in the older export format with JSON-encoded inputs, e.g. canvas.page_region.mercury.header.yml in Convene:
inputs: '{"menu_align":"right"}'
This format is deprecated since canvas:1.4.0 but still supported until 2.0.0 (https://www.drupal.org/node/3586291): ComponentTreeConfigEntityBase decodes string inputs when the entity is created, and CanvasConfigUpdater has an update path.
However, Config\Schema\ComponentInputsMapping::__construct() passes $component_instance['inputs'] unchecked to ComponentInputs::resolveConfigSchemaMapping(..., array $actual_inputs). As soon as typed configuration is built from the raw data (recipe config import/validation, before preCreate()), the TypeError is thrown.
Steps to reproduce¶
- Install Drupal CMS 2.2 (Canvas 1.12).
- Choose the Convene (or Archimedes, Healthcare, Pulse, CareSphere) site template.
- The installation aborts with the TypeError above.
Proposed resolution¶
Decode string inputs in ComponentInputsMapping, like ComponentTreeConfigEntityBase does:
$actual_inputs = $component_instance['inputs'];
if (\is_string($actual_inputs)) {
$actual_inputs = Json::decode($actual_inputs);
}
With this change all five templates install (verified with Drupal CMS 2.2, Canvas 1.12, German and English).
Lupus Decoupled Starter is affected as well: once its other installation problems are fixed (reports #13 and #40), it stops with the same TypeError, and installs with this change (verified with Canvas 1.12.0).
Remaining tasks¶
- Patch (one line +
use), test with a config entity that has JSON-encoded inputs. - Separately, the templates could re-export their configuration with a current Canvas (issues in their queues).
Additional information¶
Workaround in the German Drupal CMS installer (patch_canvas_json_inputs()).
Copy to drupal.org
Issue title:
TypeError in ComponentInputsMapping for config component trees with JSON-encoded inputs (breaks 5 Drupal CMS site templates)
Issue summary (paste it into the "Issue summary" field; project, component, category and priority are in the table above):
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>Five Drupal CMS site templates cannot be installed at all – in any language:</p>
<ul>
<li>Archimedes (Zoocha)</li>
<li>Healthcare (Kanopi)</li>
<li>Pulse (QED42)</li>
<li>CareSphere and Convene (OpenSense Labs)</li>
</ul>
<p>The installation stops with:</p>
<code>TypeError: Drupal\canvas\Plugin\DataType\ComponentInputs::resolveConfigSchemaMapping(): Argument #3 ($actual_inputs) must be of type array, string given, called in canvas/src/Config/Schema/ComponentInputsMapping.php on line 54</code>
<p>All five ship Canvas configuration (<code>canvas.content_template.*</code>, <code>canvas.page_region.*</code>) in the older export format with JSON-encoded inputs, e.g. <code>canvas.page_region.mercury.header.yml</code> in Convene:</p>
<code>inputs: '{"menu_align":"right"}'</code>
<p>This format is deprecated since canvas:1.4.0 but still supported until 2.0.0 (https://www.drupal.org/node/3586291): <code>ComponentTreeConfigEntityBase</code> decodes string inputs when the entity is created, and <code>CanvasConfigUpdater</code> has an update path.</p>
<p>However, <code>Config\Schema\ComponentInputsMapping::__construct()</code> passes <code>$component_instance['inputs']</code> unchecked to <code>ComponentInputs::resolveConfigSchemaMapping(..., array $actual_inputs)</code>. As soon as typed configuration is built from the raw data (recipe config import/validation, before <code>preCreate()</code>), the TypeError is thrown.</p>
<h3 id="summary-steps-reproduce">Steps to reproduce</h3>
<ol>
<li>Install Drupal CMS 2.2 (Canvas 1.12).</li>
<li>Choose the Convene (or Archimedes, Healthcare, Pulse, CareSphere) site template.</li>
<li>The installation aborts with the TypeError above.</li>
</ol>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>Decode string inputs in <code>ComponentInputsMapping</code>, like <code>ComponentTreeConfigEntityBase</code> does:</p>
<code>$actual_inputs = $component_instance['inputs'];
if (\is_string($actual_inputs)) {
$actual_inputs = Json::decode($actual_inputs);
}</code>
<p>With this change all five templates install (verified with Drupal CMS 2.2, Canvas 1.12, German and English).</p>
<p>Lupus Decoupled Starter is affected as well: once its other installation problems are fixed (reports #13 and #40), it stops with the same TypeError, and installs with this change (verified with Canvas 1.12.0).</p>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
<ul>
<li>Patch (one line + <code>use</code>), test with a config entity that has JSON-encoded inputs.</li>
<li>Separately, the templates could re-export their configuration with a current Canvas (issues in their queues).</li>
</ul>
<h3>Additional information</h3>
<p>Workaround in the German Drupal CMS installer (<code>patch_canvas_json_inputs()</code>).</p>