Problem/Motivation

As described in #3590586: Support block_content entities this module is not compatible with Canvas 1.4.0. Something has changed with how autocompletes are handled in Canvas causing values that are not parsed correctly.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

peter törnstrand created an issue. See original summary.

peter törnstrand’s picture

thomas.frobieter’s picture

This should have been fixed with the release of Canvas 1.4.1.

thomas.frobieter’s picture

Issue summary: View changes
StatusFileSize
new19.06 KB

The issue with version 1.4.0 has been resolved, but multivalue props no longer work. You can only select one option.

Drupal Canvas Entity Reference widget

nodes:
      type: array
      title: Single Articles
      description: "Choose specific articles."
      maxItems: 5
      items:
        type: integer
        title: Article (returns ID)
        description: "Select a node. Uses x-entity-field: nid — returns the numeric node ID."
        x-entity-type: node
        x-entity-field: nid
        x-entity-type-bundles: "article"

As you can see, there's also a new widget.
I've tried entering further nodes separated by commas, but this doesn't work either.

This is what I get from the nodes property after saving this:

0 array:1 [▼
  0 => 155
]
0 []
0 []
0 []
thomas.frobieter’s picture

Title: Not compatible with Canvas 1.4.0 » Not compatible with Canvas 1.4.0 / 1.4.1

Another thing: In the "Test: Multi-value & Taxonomy Term (x-entity-type)" SDC, I get a JS error when starting to type in the "Tags (via x-entity-type)" reference field.

Uncaught Error: NOT SUPPORTED: keyword "id", use "$id" for schema ID

  • zeeshan_khan committed 598dc0b9 on issue/3590655-canvas-14x-compatibility
    Issue #3590655: Also remove $ref from example-taxonomy-card component...

  • zeeshan_khan committed 7cf336e3 on 1.0.x
    Issue #3590655: Fix Canvas 1.4.x compatibility — remove $ref from test...
zeeshan_khan’s picture

Status: Active » Needs review

Investigation complete. Two separate fixes required.

Root cause of the NOT SUPPORTED: keyword "id" error

When PHP resolves a $ref URI (e.g. json-schema-definitions://canvas_entity_reference.module/taxonomy-term-reference or Canvas's own json-schema-definitions://canvas.module/image-uri), the justinrainbow/json-schema library's UriRetriever::retrieve() adds id: to the schema object. This is draft-04 JSON Schema behavior.

Canvas 1.4.x upgraded AJV to v8, which no longer accepts the draft-04 id keyword (only $id). Canvas's GeneratedFieldExplicitInputUxComponentSourceBase::stripNonStandardJsonSchemaKeys() strips meta:enum and x-translation-context before sending schemas to the browser, but does not strip id. Note that PropShape::normalizePropSchema() does already strip id (see the comment there), but stripNonStandardJsonSchemaKeys() was not updated when AJV was upgraded.

This affects any component using a json-schema-definitions:// $ref — including Canvas's own image and video definitions which internally reference json-schema-definitions://canvas.module/image-uri.

Fix 1 - this module (pushed to MR branch)

Removed all $ref: json-schema-definitions://canvas_entity_reference.module/... from this module's test and example components (test-multi-nodes, example-taxonomy-card). Replaced with x-entity-type: taxonomy_term which is fully equivalent and does not trigger the issue.

Also added a Canvas 1.4.x compatibility note to the README warning users that components using the legacy $ref syntax will trigger this error and recommending x-entity-type instead.

Fix 2 - Canvas core (one-line patch, needs upstream fix)

In GeneratedFieldExplicitInputUxComponentSourceBase::stripNonStandardJsonSchem aKeys(), add 'id' to the list of keys to remove:

$keys_to_remove = ['meta:enum', 'x-translation-context', 'id'];

A bug report has been filed against Canvas at https://www.drupal.org/project/canvas with this fix. Until Canvas ships a release containing the fix, sites running Canvas 1.4.x must apply this one-line patch manually (or via cweagans/composer-patches).

The patch has been added to Canvas issue - https://www.drupal.org/project/canvas/issues/3591133#comment-16592985
https://www.drupal.org/files/issues/2026-05-20/canvas-3591133-strip-id-k...

Also raised a MR in the same issue - https://git.drupalcode.org/project/canvas/-/merge_requests/1134

zeeshan_khan’s picture

Update: Our upstream patch (#3591133) was closed as a duplicate of canvas#3591028, which takes a more thorough approach — upgrading justinrainbow/json-schema to ^6.8.0 for JSON Schema Draft-07 support. This resolves the root cause at the library level.

However, canvas#3591028 has not shipped in a Canvas release yet (latest is 1.4.1). We are watching that issue for the next Canvas release.

In the meantime, the module-side fix in this MR remains the recommended workaround for sites on Canvas 1.4.x: use x-entity-type instead of $ref URIs in component YAML files — this is documented in the updated README.

Once Canvas ships the fix, we will test compatibility and close this issue.

thomas.frobieter’s picture

#3591028 shipped with 1.5.0 :)

  • zeeshan_khan committed 8010d5d9 on issue/3590655-canvas-14x-compatibility
    Issue #3590655: Update compatibility note — fixed in Canvas 1.5.0
    

  • zeeshan_khan committed 7cf336e3 on issue/3590655-canvas-14x-compatibility
    Issue #3590655: Fix Canvas 1.4.x compatibility — remove $ref from test...

  • zeeshan_khan committed f2410100 on 1.0.x
    Issue #3590655: Fix Canvas 1.4.x compatibility — remove $ref from test...
zeeshan_khan’s picture

Thanks @thomas.frobieter for the info - The root cause has been fixed in Canvas 1.5.0.

https://git.drupalcode.org/project/canvas_entity_reference/-/merge_reque...
This MR updates the README compatibility note to reflect that — replacing "a fix has been reported upstream" with "This was fixed in Canvas 1.5.0." The x-entity-type approach in test and example components was already committed to 1.0.x as a best-practice workaround for anyone still on Canvas 1.4.x.

@thomas.frobieter - the module's is also working perfectly with canvas 1.5.0 if you can try and do RTBC that will be great
Thanks

thomas.frobieter’s picture

StatusFileSize
new11.35 KB

Sure, I've tried all the examples on the module page.

Tested with Canvas 1.6!

1) Single-value taxonomy term:
The field looks correct, but there are no autocomplete suggestions.
The stored string is printed exactly as it is (as if it were a simple text field).

2) Single-value node (title):
Same as example 1.

3) Node — returns a numeric ID for use with entity_render().
It is printed as a number field, so only integer values are allowed.

4) Restrict to specific bundles:
Not tested, as it's just more explicit.

5) Multi-value with maxItems:
Same as singular values (no autocomplete), but with the multi-value UI:
Multivalue Reference UI

thomas.frobieter’s picture

Status: Needs review » Needs work

  • zeeshan_khan committed a3905365 on issue/3590655-fix-autocomplete-transform
    Issue #3590655: Fix toRecordsArray for tags widget flat record format...

  • zeeshan_khan committed 6875d917 on issue/3590655-fix-autocomplete-transform
    Issue #3590655: Fix prettier single-quote violations in transform JS
    
    CI...

  • zeeshan_khan committed df8128df on 1.0.x
    Issue #3590655: Fix entityReferenceAutocomplete transform for Canvas...
zeeshan_khan’s picture

Status: Needs work » Needs review

@thomas.frobieter Thanks for your review!
Two bugs were found in js/entity-reference-autocomplete-transform.js. Both stem from how Canvas's formStateToObject() encodes form state.

Bug 1 — single-value widget (autocomplete not saving)

formStateToObject() produces a delta-keyed object { "0": { target_id: "Label (5)" } }, not a plain array. The transform checked Array.isArray(value) and returned the object unchanged on failure. firstRecord and mainProperty then received a non-array and extracted nothing.

Fix: toRecordsArray() detects delta-keyed objects (all keys are numeric strings) and calls Object.values() to extract the records.

Bug 2 — tags widget (multi-value not saving)

The tags widget uses [prop][target_id] (no delta index), so formStateToObject() produces { target_id: "Label (5)" } (a flat record). Object.values() on that returns ["Label (5)"] — a string array. The typeof item !== "object" guard then skipped every item.

Fix: toRecordsArray() wraps flat records as [value] instead of calling Object.values().

MR: https://git.drupalcode.org/project/canvas_entity_reference/-/merge_reque...

thomas.frobieter’s picture

Status: Needs review » Needs work
StatusFileSize
new13.88 KB

@zeeshan_khan I can confirm that:

1) Single-value taxonomy term: works
2) Single-value node (title): works
3) Node — returns a numeric ID for use with entity_render(): works
5) Multi-value with maxItems: Works, but only for one item, while the configuration is:

    tags:
      type: array
      title: Tags
      maxItems: 5
      items:
        type: ["string", "null"]
        x-entity-type: taxonomy_term


This is what we get:

Drupal Canvas Sidebar with canvas entity reference test fields

  • zeeshan_khan committed ff35b6ed on issue/3590655-fix-maxitems-cardinality
    Issue #3590655: Update test to expect CARDINALITY_UNLIMITED for maxItems...

  • zeeshan_khan committed 56b617b8 on 1.0.x
    Issue #3590655: Fix maxItems cardinality breaking multi-value saves
    
zeeshan_khan’s picture

Status: Needs work » Needs review

@thomas.frobieter Thank you so much for prompt response!

Root cause identified for the maxItems issue.

When maxItems is set on an array prop, the previous code passed that value as the Drupal field cardinality (e.g. maxItems: 5 -> cardinality = 5). Drupal then renders 5 delta rows of entity_reference_autocomplete_tags. The tags widget outputs all selected values in a single text input without a delta index - all 5 rows share the form element name [prop][target_id]. Only the last submitted value survives each save, so only one item persists.

Fix in EntityReferenceShapeMatcher::apply(): array props using the tags widget always receive CARDINALITY_UNLIMITED. The maxItems constraint is a JSON Schema concern enforced by Canvas validation, not a field cardinality concern. Props using a custom x-entity-widget override still receive maxItems as cardinality.

Tested locally with maxItems: 3 on the tags prop of the test component. Three terms were saved and rendered correctly. Single-value fields and unlimited-cardinality multi-value fields are unaffected.

MR https://git.drupalcode.org/project/canvas_entity_reference/-/merge_reque... Fixes it

thomas.frobieter’s picture

Status: Needs review » Reviewed & tested by the community

Ah, got it. So the values need to be entered, separated by commas, in the flyout autocomplete field. I had suspected this during a previous test, but I don't think I tested it last time. This definitely needs better UX 😅

However, it works! I also looked at the resulting values, and everything looks as expected.

Is the UX part of the module, or do you just use the widgets from the Canvas module? Should I create another issue for that?

zeeshan_khan’s picture

Thanks for your review!

The comma-separated behaviour is inherent to entity_reference_autocomplete_tags. The widget renders all values in a single text input. Canvas's flyout exposes that input directly.

That change is within scope for this module (widget selection in EntityReferenceShapeMatcher), but it touches the transform chain and needs its own testing. A separate issue would keep it trackable.

Whether the flyout popover itself should be improved to handle comma-separated inputs more gracefully is a Canvas core question.

zeeshan_khan’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

thomas.frobieter’s picture

Okay, so this stacked UI was not the intended behavoir for multi value fields?

asdf

That would also be far from perfect, especially if there are many values. But it would be easier for users to handle than the comma-separated solution in such a small field.

I don't understand the purpose of this flyout solution either, unless the goal is to group multiple fields together. In our case, it would be better to have multiple autocomplete fields listed below each other and an "Add" button below them, provided there's no limit to the number of fields.

Anyway, it's great that everything is working again. Thanks a million!

I've created an issue for the Multivalue UI/UX; if Canvas Core ends up having to resolve it, we can just refer to that: #3608101: Better UI/UX for Multivalue Reference Fields

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.