PropShape::normalizePropSchema() does not strip $id, breaking image/video prop shape matching with justinrainbow/json-schema ≥ 6.9.0
## Problem/Motivation
justinrainbow/json-schema 6.9.0 (release notes (https://github.com/jsonrainbow/json-schema/blob/main/CHANGELOG.md#690---2026-06-05), PR #912 (https://github.com/jsonrainbow/json-schema/pull/912)) changed UriRetriever::retrieve() to annotate resolved schemas with the dialect-aware id keyword. For schemas that do not declare a $schema keyword (including Canvas's own schema.json), it now sets $id (with dollar sign) instead of id on the loaded stdClass.
PropShape::normalizePropSchema() removes id to prevent the retrieved URI from interfering with shape comparisons, but it does not remove $id. This creates a one-sided contamination: schemas resolved via UriRetriever (component props with $ref: pointing to json-schema-definitions://canvas.module/*) gain a $id key, while schemas resolved directly from $defs arrays (the well-known shapes in getWellKnownPropShapes()) do not.
## Steps to reproduce
1. Install Canvas with justinrainbow/json-schema ^6.9.0 (or bump from 6.8.x to 6.9.x in composer.json).
2. Add any SDC or JavaScript component with an image or video prop using the standard $ref: json-schema-definitions://canvas.module/image or json-schema-definitions://canvas.module/video.
3. Run ComponentSourceManager::generateComponents() (or trigger a site update that calls it — e.g. Canvas module update hook, or visiting the Canvas admin UI).
## Expected behavior
The component is generated successfully. Its image/video prop is mapped to the image_image / file_generic field type and widget.
## Actual behavior
standardize() fails to recognize the prop as a well-known image/video shape. It falls back to the resolved schema, which has no $ref. computeStorablePropShape() for Object type requires $ref to dispatch to Image/Video — without it, it returns null. ComponentMetadataRequirementsChecker logs:
Drupal Canvas does not know of a field type/widget to allow populating the image prop, with the shape {"type":"object","$id":"json-schema-definitions://canvas.module/image","properties":…}
The component is marked as not meeting requirements and is disabled (or fails to generate). Image and video components disappear from the Canvas page builder.
## Proposed fix
In PropShape::normalizePropSchema(), strip $id in addition to id:
``` // Omit the ID containing the resolved $ref URI.
// @see \JsonSchema\SchemaStorage::resolveRefSchema()
// @see \JsonSchema\Uri\UriRetriever::retrieve()
unset($normalized_prop_schema['id']);
// justinrainbow/json-schema ≥6.9.0 uses $id (dollar-prefixed) for non-draft-3/4
// schemas; strip both variants to keep normalization stable across library versions.
unset($normalized_prop_schema['$id']);
```
A longer-term fix worth considering: getWellKnownPropShapes() resolves schema.json definitions without going through UriRetriever, while prop schemas from components do go through it. The asymmetry exists because only one path triggers the URI annotation. Making both paths consistent (or simply stripping both id variants) would prevent a recurrence if justinrainbow/json-schema adds further annotation in the future.
## Workaround
Pin justinrainbow/json-schema to ~6.8.2 in your project's composer.json:
```
"justinrainbow/json-schema": "~6.8.2"
```
issue