Skip to content

fix: resolve view-bound admin singletons under @webiny/di 2.0 - #5979

Merged
adrians5j merged 3 commits into
nextfrom
claude/fix-cms-trash-bin-scope
Oct 13, 2026
Merged

adrians5j merged 3 commits into
nextfrom
claude/fix-cms-trash-bin-scope

Conversation

@adrians5j

@adrians5j adrians5j commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

@webiny/di 2.0 (#5969) builds a singleton from the container that holds its registration, not from the container that resolves it. Three admin singletons were registered on the root container but depend on something that only a view's child container registers, so they now fail to resolve:

What failed Root registration Child-only dependency
Every CMS content entries page: "No registration found for CmsModelContext" CmsTrashBinFeature (trash bin presenter and gateway adapters), via ContentEntryFeature CmsModelContext, from ContentEntriesView
Opening any CMS entry: "No registration found for RevisionsListPresenter" CmsCompareEntryRevisionsPresenter (ai-powerups) RevisionsListPresenter, from ContentEntriesView
Opening a file's details in File Manager ReenrichWithAiPresenter (app-file-manager) FileDetailsPresenter, from FileManagerView

Under di 1.x all three worked by accident. The first view to resolve them built them against its own child, the root cached the result, and every later view shared it. The CMS trash bin, for example, kept the model of whichever list opened first.

Fix

  • Trash bin. CmsTrashBinFeature registers on the content entries view's child container, next to CmsModelContext, and ContentEntryFeature no longer registers it. Website Builder already does the same with its pages trash bin (PagesList.tsx). Nothing outside the trash bin uses the three use-case features it registers.
  • The two presenters are registered with inContainerScope() instead of inSingletonScope(). A container-scoped instance is built from the container that resolves it, here the view's child, and cached there. The compare-revisions menu item and its overlays still share one instance per view.

How the cases were found

I traced every createChildContainer() site in the admin packages and checked each singleton reachable from the root for a dependency, direct or transitive, that only a child registers. These three are all the cases. The app-aco folder features, the record-locking, workflow and scheduler decorators, and the collaboration, notifications and webhooks presenters were checked and are fine. One known behaviour change remains that doesn't crash. Root singletons that read LocalStorage now get the root instance rather than the tenant-prefixed one the tenancy provider registers. That affects the GraphQL playground's tabs and query history, which are now shared across tenants. It's left for a separate change.

Testing

  • yyb builds. Tests pass: app-headless-cms content entry presenters (8 files, 58 tests), app-file-manager (13 files, 124 tests), ai-powerups (11 files, 89 tests).
  • Checked in the admin:
    • CMS lists: the Products and Articles lists render. After trashing a product, the Products trash bin lists it and the Articles one is empty, and restoring it works.
    • CMS entry form: an entry form renders, and "Compare revisions" in its menu opens the compare drawer.
    • File Manager: a file's details drawer opens, and "Re-enrich with AI" opens its dialog. With no vision model configured locally, it shows the expected message.
    • No console errors from these pages. The one warning, a duplicate React key in StreamingPlaceholder, is unrelated.
  • No regression test. The bug is about which container a feature is registered on, and the existing tests build their own containers.

Products trash bin listing the trashed entry

Workspace: wby-next2 · 🧹 MERGE 6.5.0 => NEXT

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • The trash bin is now associated with the content entries view and its active content model, rather than being registered globally. This aligns trash bin behavior with the model currently in use when working with content entries.
    • Revision comparisons and AI re-enrichment now use the appropriate view context, helping these tools work consistently with the content and file details currently displayed.

adrians5j and others added 2 commits October 13, 2026 09:42
… view

Every content entries page failed with "No registration found for
CmsModelContext". The trash bin's gateway adapters read CmsModelContext,
which only the per-view child container registers, but
CmsTrashBinFeature registered them as singletons on the root.

@webiny/di 2.0 (#5969) builds a singleton from the container that holds
its registration, so the root could no longer reach CmsModelContext.
Under 1.x the first view to open the trash bin built the adapters
against its own model, and every later view shared that instance.

The trash bin now registers on the content entries view's child
container, next to CmsModelContext, as Website Builder does with its
pages trash bin. Each model's view gets its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🚓 Slop Cop

✅ Nothing worth flagging. The diff looks consistent with the PR's stated intent and the code-style rules.

Small, coherent fix matching its stated intent; no integrity or style issues found.

Automated, non-blocking heads-up from an LLM. It can be wrong — use your judgment. Regenerates on every push.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 38bdd749-7955-4582-8258-e751bf92c234
📥 Commits

Reviewing files that changed from the base of the PR and between 5271cbc and 6e1a735.

📒 Files selected for processing (2)
  • packages/ai-powerups/src/admin/presentation/CmsCompareEntryRevisions/feature.ts
  • packages/app-file-manager/src/modules/AiEnrichment/feature.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 1 remain after this review.

📝 Walkthrough

CmsTrashBinFeature registration moves from ContentEntryFeature to the content entries view child container. Two presenters change from singleton scope to container scope.

Changes: Trash-bin feature registration

Layer / File(s) Summary
Register trash-bin feature in the content entries view
packages/app-headless-cms/src/presentation/contentEntries/views/ContentEntriesView.tsx, packages/app-headless-cms/src/features/contentEntry/feature.ts
ContentEntriesView registers CmsTrashBinFeature in its child container alongside CmsModelContext. ContentEntryFeature no longer imports or registers it.

Presenter container scopes

Layer / File(s) Summary
Scope the revisions presenter to its container
packages/ai-powerups/src/admin/presentation/CmsCompareEntryRevisions/feature.ts
CmsCompareEntryRevisionsPresenterImplementation is registered in container scope. The comments describe sharing the instance between the header menu item and overlays.
Scope the AI enrichment presenter to its container
packages/app-file-manager/src/modules/AiEnrichment/feature.ts
ReenrichWithAiPresenter is registered in container scope.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 6e1a7

The presenter scope changes have no identified merge-blocking issue. Merge after normal checks.

Pre-merge checks · Passed 5
Passed Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main change: fixing view-bound admin singletons for @webiny/di 2.0. It is concise and specific.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Two more root singletons depend on presenters that only a view's child
container registers, so under @webiny/di 2.0 they fail the same way the
CMS trash bin did:

- CmsCompareEntryRevisionsPresenter (ai-powerups) reads
  RevisionsListPresenter from the content entries view. Opening any CMS
  entry failed with "No registration found for RevisionsListPresenter".
- ReenrichWithAiPresenter (app-file-manager) reads FileDetailsPresenter
  from the File Manager view, so opening a file's details would fail.

Both are now registered with inContainerScope(). A container-scoped
instance is built from the container that resolves it, which is the
view's child, and is cached there, so components in one view still
share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adrians5j adrians5j changed the title fix(app-headless-cms): register the CMS trash bin per content entries view fix: resolve view-bound admin singletons under @webiny/di 2.0 Oct 13, 2026
@adrians5j
adrians5j merged commit 38efa2c into next Oct 13, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant