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