Problem/Motivation

`TrashStorageTrait::buildQuery()` is already workspace-aware — it joins
`workspace_association`, repoints the `revision` join at the workspace revision,
and filters `deleted IS NULL`. On a cold cache, loading an entity trashed inside
the active workspace correctly returns nothing.

With a warm `cache.entity` it does not, because the load path never reaches
`buildQuery()`:

```
getFromStaticCache() entity.memory_cache
getFromStorage()
→ preLoad() hook_entity_preload()
→ getFromPersistentCache() cache.entity ← answers here
→ doLoadMultiple() → buildQuery() ← trash's workspace filter
```

`WorkspaceProviderBase::entityPreload()` normally claims every tracked ID and
`preLoad()` removes it from `$ids`, so the workspace-agnostic cache is never
consulted. Trash breaks that: the tracked revision is soft-deleted, so
`buildQuery()` filters it out of the `loadMultipleRevisions()` call preload makes,
the ID goes unclaimed, and `cache.entity` returns the **Live default revision** —
not deleted, still published, so it renders while the workspace is active.

`TrashCacheBackendTrait` can't catch this: it filters on write via
`Trash::entityIsDeleted($data)`, but in a workspace the deletion lives in a
pending revision while the cached Live default is not deleted.

Affects every entity type that is trash-enabled and workspace-supported. Entity
queries are fine (they use Trash's decorated query factory), so it surfaces on
reference-based loads — a referenced media item, node or block_content that keeps
rendering after being trashed in the workspace.

Steps to reproduce

With Trash and Workspaces enabled, and Trash enabled for `media` (any
trash-enabled, workspace-supported entity type reproduces it):

1. In Live, create an Image media item and a page that renders it through an
entity reference field (not a view).
2. View the page in Live so the media entity lands in `cache.entity`.
3. Switch to workspace A. Delete the media item.
4. View the page again in workspace A.

**Expected:** the media does not resolve, so nothing is rendered for it — the
behaviour you get on a cold cache.
**Actual:** the media still resolves and still renders. Flushing caches produces
the expected result until the entity is loaded in Live again.

Same reproduction with an entity reference to a trashed node or block_content.

Proposed resolution

Override `getFromPersistentCache()` in `TrashStorageTrait`, beside the
`buildQuery()` it protects: skip the cache for IDs tracked in the active
workspace, then return them to `$ids` so they resolve through
`doLoadMultiple()`/`buildQuery()`.

The lookup is exact rather than heuristic — `preLoad()` has already removed every
ID whose workspace revision *was* returned, so any surviving tracked ID is one
Trash filtered out. Guards keep it off the common paths: non-empty `$ids`, trash
context `active`, Workspaces installed, entity type supported, non-default
workspace active. `loadUnchanged()` is fixed by the same override.

Cost is one indexed `workspace_association` lookup per multi-load inside a
workspace — the same query Workspaces already runs for the same IDs in
`entityPreload()`. If maintainers prefer, Trash could instead record the IDs it
filtered during preload and consult that in-request list, avoiding the query
entirely; that's harder to wire up (only revision IDs are known at the filtering
point), so the simpler version is proposed first.

Issue fork trash-3616230

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

paranojik created an issue. See original summary.

paranojik’s picture

Status: Active » Needs review
alecsmrekar’s picture

Assigned: paranojik » Unassigned
Status: Needs review » Reviewed & tested by the community
amateescu’s picture

Status: Reviewed & tested by the community » Needs work

Reviewed, and the first point requires a new approach for this fix.

  • amateescu committed c0562a89 on 3.1.x authored by paranojik
    fix: #3616230 Entities trashed inside a workspace are still loaded (and...

  • amateescu committed 5f4fe3fc on 3.x authored by paranojik
    fix: #3616230 Entities trashed inside a workspace are still loaded (and...
amateescu’s picture

Status: Needs work » Fixed

Merged into 3.1.x and cherry-picked to 3.x, thanks!

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.

Status: Fixed » Closed (fixed)

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