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
After upgrade from angular 7 to 15 page rendering fails with error #53245
`RangeError: Invalid string length
at Array.join (<anonymous>)
at Array.toString (<anonymous>)
at getOrCreateNodeInjectorForNode (vendor.js:239616:63)
at initializeDirectives (vendor.js:247200:24)
at resolveDirectives (vendor.js:247187:7)
at elementStartFirstCreatePass (vendor.js:249740:3)
at ɵɵelementStart (vendor.js:249774:41)
at Module.ɵɵelement (vendor.js:249849:3)
at PageaccruallistComponent_Template (src_ts_generated-sources_page-accrual-list_module_ts.js:91587:63)
at executeTemplate (vendor.js:246773:5)`
Please provide the environment you discovered this bug in (run ng version)
This would require a reproduction to be actionable. I think your best path forward would be to have a breakpoint for when the exception occurs, to them inspect the values that result in this error.
How I 'solved' the issue... My SVG had a lot of directives and a lot of html attributes attached to it as I mentioned in my comment above. Moved all of them ether away or to the parent element helped a lot. I had markForCheck() called number of times (in the component that handles the SVG) and reducing that helped as well. I am not sure that I've solved the issue completely but at least these adjustments changed threshold until error happens again. I hope that this can help you guys as well...
Okay, this appears to fail because the number of child elements exceeds the bitsize that is available for children in an internal data structure.
In development mode, the following root cause error is reported:
ASSERTION ERROR: Parent injector must be pointing past HEADER_OFFSET. [Expected=> 22 > 4 <=Actual]
@JoostK Could you give instructions or workaround how to increase internal data structure size? We've decreased by 5 times number of child elements, but error still appears,
It doesn't look like the problem will be resolved any time soon...
chunk-6HSZQENR.js?v=856b5065:8014 ERROR RangeError: Maximum call stack size exceeded
at executeTemplate (chunk-6HSZQENR.js?v=856b5065:10601:5)
at renderView (chunk-6HSZQENR.js?v=856b5065:11387:7)
at renderComponent (chunk-6HSZQENR.js?v=856b5065:11369:3)
at renderChildComponents (chunk-6HSZQENR.js?v=856b5065:11416:5)
at renderView (chunk-6HSZQENR.js?v=856b5065:11401:7)
at renderComponent (chunk-6HSZQENR.js?v=856b5065:11369:3)
at renderChildComponents (chunk-6HSZQENR.js?v=856b5065:11416:5)
at renderView (chunk-6HSZQENR.js?v=856b5065:11401:7)
at ComponentFactory.create (chunk-6HSZQENR.js?v=856b5065:14044:9)
at _ApplicationRef.bootstrap (chunk-6HSZQENR.js?v=856b5065:22471:38)
@kochetkovSergeY We are following the migration guide and we've almost finished the migration
I don't see any point in switching to 8 and so on...
Hi @kochetkovSergeY, I recently upgraded two very large Angular projects that had a significant version leap and I encountered similar error messages during the process. I’ll try to track down exactly when I ran into this issue and see if I can help.
That said, I strongly agree with the recommendation not to skip major versions. It's important to upgrade incrementally—go from v8 to v9 first, then v9 to v10, and so on. This allows ng update to handle necessary migration steps properly, especially if you're using packages like Angular Material.
This recommendation is explicitly stated in the Angular documentation:
You can ng update to any version of Angular, provided that the following criteria are met:
The version you want to update to is supported.
The version you want to update from is within one major version of the version you want to upgrade to.
For example, you can update from version 11 to version 12, provided that version 12 is still supported. If you want to update across multiple major versions, perform each update one major version at a time. For example, to update from version 10 to version 12:
Update from version 10 to version 11.
Update from version 11 to version 12.
More than that, if you have 3rd party dependencies, you will also have to resolve them before you hop to the next version. For example, I had @microsoft/applicationinsights-angularplugin-js 2.6.2, which wasn't compatible with v13. I had to refer to their Compatibility Matrix to find out that I needed to upgrade to 2.9.2. In many cases, though, other libraries don’t provide a clear compatibility guide—so you may need to dig through commit histories or cross-reference release dates between Angular and the library to find a working version. Another example, if you are using @angular/flex-layout, you will find out that the team stopped publishing new releases starting in v15 so you will have to manually migrate to a modern CSS tooling like Tailwind or at least convert your flex-layout directives to their raw CSS equivalent. Even libraries like RxJS may introduce stealth patches that don’t break your build but can lead to runtime issues. So you also have to consider regression tests on your features after each upgrade to catch any unexpected behavior early.
Root cause found. Still reproducible on v22.2.1 (current latest) and v18.2.14. Proposed fix is two constants.
Root cause
The location of a node's parent injector is packed into one number (RelativeInjectorLocation): the low 15 bits hold the index of the parent injector in the LView, bits 16+ hold the declaration-view offset.
packages/core/src/render3/di.ts, getParentInjectorLocation(): returns tNode.parent.injectorIndex or parentTNode.injectorIndex | (declarationViewOffset << ViewOffsetShift) without a range check
tNode.injectorIndex is lView.length at the moment the injector is created (getOrCreateNodeInjectorForNode), i.e. an absolute index into the LView. The LView grows with the template: HEADER_OFFSET + 1 slot per node + 1 per binding + 1 per directive instance + 9 per element that has at least one directive (8 bloom words + parent location). An element with a single directive/component therefore costs ~11 slots, and once a template holds roughly 2,900 of them, every injector created after that lands at an index >= 32768. Each descendant (or child-component node) that points at it gets a truncated parent index.
Depending on where the truncated index lands:
dev mode: ASSERTION ERROR: Parent injector must be pointing past HEADER_OFFSET (this issue)
prod mode: the index hits a header slot holding an array/LView, and parentLView[parentIndex + i] | parentData[parentIndex + i] calls Array.prototype.toString -> RangeError: Invalid string length (this issue) or Maximum call stack size exceeded
any other slot: the cumulative bloom filter is silently filled with garbage; the first visible effect is a bogus NG0201: No provider found for X for a token provided by an ancestor element
index >= 65536: the view-offset bits are corrupted as well and getParentInjectorView walks past the root (TypeError: Cannot read properties of null (reading '1'))
The limit is per LView. Embedded views (*ngIf, @if, @for, ng-template) and child components get their own index space, which is why most apps never hit it, and why "reduce the number of children" did not help here (bindings and directive instances count too).
Minimal reproduction (Node, same runtime code path as the browser)
Threshold check: 28 (HEADER_OFFSET) + 2851 + 2851 * 10 = 31389 passes; 28 + 3000 + 3000 * 10 = 33028 fails. The number in the assertion matches the arithmetic exactly: host #2974 gets injector index 28 + 3000 + 2974 * 10 = 32768, masked to 0, hence [Expected=> 28 > 0 <=Actual] on v22 ([Expected=> 25 > 7] on v18, where HEADER_OFFSET is 25).
Proposed fix
Widen the index part of RelativeInjectorLocation:
exportconstenumRelativeInjectorLocationFlags{InjectorIndexMask=0b11111111111111111111,// 20 bits (was 15)ViewOffsetShift=20,// was 16NO_PARENT=-1,}
Those two constants are the only thing the runtime reads (getParentInjectorIndex, getParentInjectorViewOffset, getParentInjectorLocation). The value stays inside V8's 31-bit SMI range (20 bits index + 10 bits view offset), which allows ~1M LView slots per template and still 1023 nested declaration views. I applied exactly this change to the 22.2.1 bundle: all failing cases above pass (3,000 and 12,000 hosts, dev and prod, the NG0201 case, the >= 65536 case), and the cases with non-zero view offsets (@for, *ngIf/@if blocks, nested components) still pass.
Independently of that, getParentInjectorLocation() should assert injectorIndex <= InjectorIndexMask in dev mode with a message that says the template is too large and how to split it, instead of the current assertion / RangeError that gives no hint.
Hello, we reviewed this issue and determined that it doesn't fall into the bug report or feature request category. This issue tracker is not suitable for support requests, please repost your issue on StackOverflow using tag angular.
If you are wondering why we don't resolve support issues via the issue tracker, please check out this explanation.
getParentInjectorLocation() should assert injectorIndex <= InjectorIndexMask in dev mode with a message that says the template is too large and how to split it, instead of the current assertion / RangeError that gives no hint.
Activity
JoostK commentedon Nov 29, 2023
This would require a reproduction to be actionable. I think your best path forward would be to have a breakpoint for when the exception occurs, to them inspect the values that result in this error.
kochetkovSergeY commentedon Nov 29, 2023
Here is example:
https://stackblitz.com/edit/stackblitz-starters-xejxq3
But it's not working on stackblitz, you can download it, install dependencies and run npm run start.
Then on the start page there is a link "link to accrual-list" to child huge page
you have to wait few minutes after clicking the link, browser stuck for some time - then the error occures in console
JoostK commentedon Nov 29, 2023
Okay, this appears to fail because the number of child elements exceeds the bitsize that is available for children in an internal data structure.
In development mode, the following root cause error is reported:
spock123 commentedon Nov 29, 2023
@kochetkovSergeY if I were you I would migrate from v7 -> v8 first,.. and so on
kochetkovSergeY commentedon Nov 30, 2023
This message does not seem clear to everyone. I think this must be changed to more understandable variant
kochetkovSergeY commentedon Nov 30, 2023
We are following the migration guide and we've almost finished the migration
I don't see any point in switching to 8 and so on...
23 remaining items
lanminik commentedon Mar 6, 2024
How I 'solved' the issue... My SVG had a lot of directives and a lot of html attributes attached to it as I mentioned in my comment above. Moved all of them ether away or to the parent element helped a lot. I had markForCheck() called number of times (in the component that handles the SVG) and reducing that helped as well. I am not sure that I've solved the issue completely but at least these adjustments changed threshold until error happens again. I hope that this can help you guys as well...
venkatesh-gardas commentedon Mar 20, 2024
@alxhub
@atscott
@JoostK
Please provide any workaround or update on this issue.
kochetkovSergeY commentedon Apr 11, 2024
@JoostK Could you give instructions or workaround how to increase internal data structure size? We've decreased by 5 times number of child elements, but error still appears,
It doesn't look like the problem will be resolved any time soon...
atscott commentedon Apr 11, 2024
I've made a much smaller reproduction here: https://stackblitz.com/edit/stackblitz-starters-ew6f7z (again, it has to be downloaded and run locally)
kochetkovSergeY commentedon May 24, 2024
Angular 18 - the problem is still occurs…
Example - https://stackblitz.com/edit/stackblitz-starters-cj1r3m
Error stack:
kochetkovSergeY commentedon Aug 21, 2024
any update?
apappas1129 commentedon Jun 13, 2025
Hi @kochetkovSergeY, I recently upgraded two very large Angular projects that had a significant version leap and I encountered similar error messages during the process. I’ll try to track down exactly when I ran into this issue and see if I can help.
That said, I strongly agree with the recommendation not to skip major versions. It's important to upgrade incrementally—go from v8 to v9 first, then v9 to v10, and so on. This allows
ng updateto handle necessary migration steps properly, especially if you're using packages like Angular Material.This recommendation is explicitly stated in the Angular documentation:
More than that, if you have 3rd party dependencies, you will also have to resolve them before you hop to the next version. For example, I had
@microsoft/applicationinsights-angularplugin-js2.6.2, which wasn't compatible with v13. I had to refer to their Compatibility Matrix to find out that I needed to upgrade to 2.9.2. In many cases, though, other libraries don’t provide a clear compatibility guide—so you may need to dig through commit histories or cross-reference release dates between Angular and the library to find a working version. Another example, if you are using@angular/flex-layout, you will find out that the team stopped publishing new releases starting in v15 so you will have to manually migrate to a modern CSS tooling like Tailwind or at least convert yourflex-layoutdirectives to their raw CSS equivalent. Even libraries like RxJS may introduce stealth patches that don’t break your build but can lead to runtime issues. So you also have to consider regression tests on your features after each upgrade to catch any unexpected behavior early.kochetkovSergeY commentedon Oct 6, 2026
Root cause found. Still reproducible on v22.2.1 (current latest) and v18.2.14. Proposed fix is two constants.
Root cause
The location of a node's parent injector is packed into one number (
RelativeInjectorLocation): the low 15 bits hold the index of the parent injector in theLView, bits 16+ hold the declaration-view offset.packages/core/src/render3/interfaces/injector.ts:InjectorIndexMask = 0b111111111111111(max 32767),ViewOffsetShift = 16packages/core/src/render3/di.ts,getParentInjectorLocation(): returnstNode.parent.injectorIndexorparentTNode.injectorIndex | (declarationViewOffset << ViewOffsetShift)without a range checkpackages/core/src/render3/util/injector_utils.ts,getParentInjectorIndex():parentLocation & InjectorIndexMasktNode.injectorIndexislView.lengthat the moment the injector is created (getOrCreateNodeInjectorForNode), i.e. an absolute index into theLView. TheLViewgrows with the template:HEADER_OFFSET+ 1 slot per node + 1 per binding + 1 per directive instance + 9 per element that has at least one directive (8 bloom words + parent location). An element with a single directive/component therefore costs ~11 slots, and once a template holds roughly 2,900 of them, every injector created after that lands at an index >= 32768. Each descendant (or child-component node) that points at it gets a truncated parent index.Depending on where the truncated index lands:
ASSERTION ERROR: Parent injector must be pointing past HEADER_OFFSET(this issue)parentLView[parentIndex + i] | parentData[parentIndex + i]callsArray.prototype.toString->RangeError: Invalid string length(this issue) orMaximum call stack size exceededNG0201: No provider found for Xfor a token provided by an ancestor elementgetParentInjectorViewwalks past the root (TypeError: Cannot read properties of null (reading '1'))The limit is per
LView. Embedded views (*ngIf,@if,@for,ng-template) and child components get their own index space, which is why most apps never hit it, and why "reduce the number of children" did not help here (bindings and directive instances count too).Minimal reproduction (Node, same runtime code path as the browser)
Threshold check:
28 (HEADER_OFFSET) + 2851 + 2851 * 10 = 31389passes;28 + 3000 + 3000 * 10 = 33028fails. The number in the assertion matches the arithmetic exactly: host #2974 gets injector index28 + 3000 + 2974 * 10 = 32768, masked to0, hence[Expected=> 28 > 0 <=Actual]on v22 ([Expected=> 25 > 7]on v18, whereHEADER_OFFSETis 25).Proposed fix
Widen the index part of
RelativeInjectorLocation:Those two constants are the only thing the runtime reads (
getParentInjectorIndex,getParentInjectorViewOffset,getParentInjectorLocation). The value stays inside V8's 31-bit SMI range (20 bits index + 10 bits view offset), which allows ~1MLViewslots per template and still 1023 nested declaration views. I applied exactly this change to the 22.2.1 bundle: all failing cases above pass (3,000 and 12,000 hosts, dev and prod, theNG0201case, the >= 65536 case), and the cases with non-zero view offsets (@for,*ngIf/@ifblocks, nested components) still pass.Independently of that,
getParentInjectorLocation()should assertinjectorIndex <= InjectorIndexMaskin dev mode with a message that says the template is too large and how to split it, instead of the current assertion /RangeErrorthat gives no hint.JeanMeche commentedon Oct 6, 2026
Hello, we reviewed this issue and determined that it doesn't fall into the bug report or feature request category. This issue tracker is not suitable for support requests, please repost your issue on StackOverflow using tag
angular.If you are wondering why we don't resolve support issues via the issue tracker, please check out this explanation.
JoostK commentedon Oct 6, 2026
This is worth doing IMO
atscott commentedon Oct 6, 2026
Would you mind sending a PR over for this? The fix seems reasonable and correct.
kochetkovSergeY commentedon Oct 6, 2026
Yes, I send a PR tomorrow