You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Failing to return some nested data within content types #16
We have a somewhat complex component library with fairly heavy levels of nesting. We're in active development and have recently seen fields not being returned by queries using populate=all. Components that previously returned their full nested dataset are not
Reviewing the plugin readme, you state it builds a standard Strapi populate query via middleware. Is it possible that a sufficiently complex component structure might be hitting the url limits?
Url limits should not apply here because it creates a populate query inside the node env and doesn't pass them through any url.
There was another bug which is fixed now (#17) that might be related to yours. 🤔 Could you try if v1.2.5 fixes your issue?
If not can you provide more details? What kind of field (relations, components, dz, string, etc.)? How does your component library schema look like? Or could you provide some kind of reproduction steps? 🙏
Unfortunately, during testing, it looks like some of our more deeply nested components still aren't being returned in the data response. All we're getting back is that component id. I did try both with and without the caching config set (in case it's implemented in some way).
Some more detail on our schemas. We build with a lot of reuse with an atomic structure. The example I'm seeing the issue on presently is similar to the following:
We're using a full access token and I've checked all permissions.
I suspect part of the issue might be due to the size/complexity of our full schema. We didn't start noticing issues until fairly late in development.
Other components and content types have similar issues. We've seen nested assets not having the entire asset object being returned, we've tested the buttons where they're used in standalone areas, and the button data might return, but not the nested page_link.
Ex. we use this masthead component on all pages, and on some content types, the image isn't being returned.
This isn't too efficient but it enables some nice scenarios which aren't possible with the current implementation where every entiy can only occur once, otherwise nested entities won't be populated.
I would let this switch in the config by two separates settings, where you have to enable either one or the other way.
Although the fix is appreciated (as it fixes issues), this still doesn't work for some cases.
A recursion can't be detected properly by looking at the entity type only.
A recursion occurs when the same entity instance (same documentID, id) repeats somewhere as a child.
Then the endless loop happens.
So the depth limiter from above is still a thing, at least for my uses cases.
I appreciate the quick compatibility fix for recent strapi versions, thank you!
Your algorithm is actually correct — parentsModelUids tracks the exact DFS call stack, which is the standard way to detect directed cycles. The same type appearing in different branches (not ancestor→descendant) won't be blocked.
There are two real improvements worth making:
Replace binary include-check with occurrence count — this lets self-referential schemas (category trees, nested menus) populate N levels deep instead of hard-stopping at 1:
Sort the cache key ancestors — the result only depends on the set of ancestors (not their order), so two calls with the same ancestors in different order produce identical queries but currently miss the cache:
Sure. You need a schema with mutual references to hit this case — say two components that can contain each other:
Page → CompA, CompB
CompA → CompB (nested)
CompB → CompA (nested, mutual)
Both → Media
When building Page's populate, Media gets called twice — once via each path:
Path parentsModelUids passed to getPopulateQuery('Media', ...)
Page → CompA → CompB → Media ['Page', 'CompA', 'CompB']
Page → CompB → CompA → Media ['Page', 'CompB', 'CompA']
Current cache keys (joined in call order):
'Page|CompA|CompB|Media' ← first call, computed and cached
'Page|CompB|CompA|Media' ← second call, cache MISS — recomputed
With sorted key:
'CompA|CompB|Media|Page' ← first call, computed and cached
'CompA|CompB|Media|Page' ← second call, cache HIT ✓
Both calls produce identical queries because cycle detection only cares about which ancestors are blocked, not the order you encountered them. The result for Media under {Page, CompA, CompB} is the same regardless of traversal order.
The impact is minor in small schemas but grows with mutual references and dynamic zones that include overlapping component sets.
Activity
faessler commentedon Nov 3, 2025
Hello @IanBoyte 👋 Thx for your bug report.
Url limits should not apply here because it creates a populate query inside the node env and doesn't pass them through any url.
There was another bug which is fixed now (#17) that might be related to yours. 🤔 Could you try if v1.2.5 fixes your issue?
If not can you provide more details? What kind of field (relations, components, dz, string, etc.)? How does your component library schema look like? Or could you provide some kind of reproduction steps? 🙏
IanBoyte commentedon Nov 13, 2025
Thanks, I've swapped the plugin back and am having my team test.
IanBoyte commentedon Nov 13, 2025
@faessler Just realized part of the issue I was having was from copying the example usage:
relationsis misspelled.faessler commentedon Nov 13, 2025
Oh my 🤦🏼♂️ Thanks for the report. Gonna fix the docs today.
Also just a fyi the
cache: booleanconfig option hasn‘t been released yet. I need to write some tests.fix(#16): correct spelling in docs
github-actions commentedon Nov 13, 2025
IanBoyte commentedon Nov 13, 2025
Unfortunately, during testing, it looks like some of our more deeply nested components still aren't being returned in the data response. All we're getting back is that component id. I did try both with and without the caching config set (in case it's implemented in some way).
IanBoyte commentedon Nov 13, 2025
Some more detail on our schemas. We build with a lot of reuse with an atomic structure. The example I'm seeing the issue on presently is similar to the following:
Our relevant content structures:
Content type: page
Module: contentBlock
Molecule: commonModuleHeader
Molecule: buttonGroup
Atom: button
Atom: internalLink
Our content schema would be similar to the following:
What we would see returned, for example, is
faessler commentedon Nov 14, 2025
Thanks for the schema! I rebuilt it in the sandbox. Unlike you I got all the data I'd expect. 🤔
Followup questions:
&status=draft)IanBoyte commentedon Nov 14, 2025
"@strapi/strapi": "^5.29.0"
All pages being tested are published.
We're using a full access token and I've checked all permissions.
I suspect part of the issue might be due to the size/complexity of our full schema. We didn't start noticing issues until fairly late in development.
Other components and content types have similar issues. We've seen nested assets not having the entire asset object being returned, we've tested the buttons where they're used in standalone areas, and the button data might return, but not the nested page_link.
Ex. we use this masthead component on all pages, and on some content types, the image isn't being returned.
vs
IanBoyte commentedon Nov 14, 2025
If it's helpful, let me know and I can provide a link to a zip of the full schema.
zhawzid-ottj commentedon Dec 9, 2025
The problem for some cases (sorts of nested containers scenarios)
is the recently added "prevent infinite loop" check.
You can also implement a max depth guard like this:
and add depth+1 to every recursive call like this (example):
then tweak this:
This isn't too efficient but it enables some nice scenarios which aren't possible with the current implementation where every entiy can only occur once, otherwise nested entities won't be populated.
I would let this switch in the config by two separates settings, where you have to enable either one or the other way.
Cheers
faessler commentedon Apr 16, 2026
Should be fixed with https://www.npmjs.com/package/strapi-plugin-populate-all/v/1.5.1.
zhawzid-ottj commentedon Apr 18, 2026
Although the fix is appreciated (as it fixes issues), this still doesn't work for some cases.
A recursion can't be detected properly by looking at the entity type only.
A recursion occurs when the same entity instance (same documentID, id) repeats somewhere as a child.
Then the endless loop happens.
So the depth limiter from above is still a thing, at least for my uses cases.
I appreciate the quick compatibility fix for recent strapi versions, thank you!
zhawzid-ottj commentedon Apr 20, 2026
This is what Claude comes up with:
Your algorithm is actually correct — parentsModelUids tracks the exact DFS call stack, which is the standard way to detect directed cycles. The same type appearing in different branches (not ancestor→descendant) won't be blocked.
There are two real improvements worth making:
Sure. You need a schema with mutual references to hit this case — say two components that can contain each other:
When building Page's populate, Media gets called twice — once via each path:
Path parentsModelUids passed to getPopulateQuery('Media', ...)
Current cache keys (joined in call order):
With sorted key:
Both calls produce identical queries because cycle detection only cares about which ancestors are blocked, not the order you encountered them. The result for Media under {Page, CompA, CompB} is the same regardless of traversal order.
The impact is minor in small schemas but grows with mutual references and dynamic zones that include overlapping component sets.
feat(recursion): allow N-level deep self-recursion population (#44)
faessler commentedon Jun 17, 2026
Defining reoccurrence level per model is now possible with new version
1.6.0.You can extend config like this:
See #44 for more details.