normalizePropSchema() strips id but resolver writes $id, so object $ref props (e.g. canvas.module/image) never register
**Version:** 1.5.0 **Component:** Code **Problem** Any SDC whose prop uses an object `$ref` such as `json-schema-definitions://canvas.module/image` is silently dropped. No `component` config entity is created. Default content that references such a component then fails validation with a fatal `AssertionError`, which aborts recipe content import during site install: `AssertionError: assert($component instanceof Component)`\ ` src/PropSource/DefaultRelativeUrlPropSource.php:41`\ ` Component::load($componentId) returned NULL` The requirements checker reports the prop as unsupported: ``Drupal Canvas does not know of a field type/widget to allow populating the `media` prop, with the shape {"type":"object","$id":"…/image", …}.`` This happens even though an Image media type exists and Media Library is enabled, i.e. the conditions the media-source matcher needs are all met. **Cause** `PropShape::standardize()` resolves the prop schema and tries to match it back to a well-known shape so it can be reduced to a bare `$ref`. The resolved schema carries the resolved-ref URI in a top-level key. `normalizePropSchema()` removes it with: `// Omit the ID containing the resolved $ref URI. unset($normalized_prop_schema['id']);` The resolver writes the key as `$id`, not `id`, so it is never removed. The resolved+normalized schema then differs from the well-known shape by exactly that one key: `well-known: {"type":"object","properties":{…}} component: {"type":"object","$id":"…/image","properties":{…}}` The `array_search()` against well-known shapes fails, `standardize()` returns the resolved object form instead of `{type:object, $ref:…/image}`, and `canvas_storable_prop_shape_alter()` (which matches on `$ref`) never fires. No storable prop shape, so the component is rejected. **Steps to reproduce** 1. Theme/module with an SDC prop using `$ref: json-schema-definitions://canvas.module/image` (the stock test component `image-srcset-candidate-template-uri` uses this pattern). 2. An Image media type present. 3. Install/rebuild and check whether the component gets a `component` entity. Result: no entity is created; `checkRequirements()` throws `ComponentDoesNotMeetRequirementsException` with the "does not know of a field type/widget" message for the image shape. **Verification of cause and fix** With the leftover `$id` removed before the well-known comparison, the match succeeds, `standardize()` returns the `$ref` form, and `getStorablePropShape()` returns a shape, the component registers. **Proposed fix** In `normalizePropSchema()`, strip the key the resolver actually writes: ``` unset($normalized_prop_schema['id']); unset($normalized_prop_schema['$id']); ``` **Environment** * drupal/canvas 1.5.0 * justinrainbow/json-schema 6.9.0 (Canvas requires `^6.8.0`; worth checking whether this key changed from `id` to `$id` across that range, since that determines whether older installs were affected) * Drupal 11.3, PHP 8.4 **AI disclaimer:** Debugged this on my local machine but asked my agent to make a summary to create this issue.
issue