angular/angular · warning
The 'allowSignalWrites' flag is deprecated and no longer imp
Error message
The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)
What it means
effect() was called with an options object containing allowSignalWrites. Since Angular 19, signal writes inside effects are always allowed and the flag is a complete no-op; passing it only produces this dev-mode deprecation warning. The effect behaves identically with or without it.
Source
Thrown at packages/core/src/render3/reactivity/effect.ts:153
* @publicApi 20.0
*/
export function effect(
effectFn: (onCleanup: EffectCleanupRegisterFn) => void,
options?: CreateEffectOptions,
): EffectRef {
ngDevMode &&
assertNotInReactiveContext(
effect,
'Call `effect` outside of a reactive context. For example, schedule the ' +
'effect inside the component constructor.',
);
if (ngDevMode && !options?.injector) {
assertInInjectionContext(effect);
}
if (ngDevMode && options?.allowSignalWrites !== undefined) {
console.warn(
`The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)`,
);
}
const injector = options?.injector ?? inject(Injector);
let destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
let node: EffectNode;
const viewContext = injector.get(ViewContext, null, {optional: true});
const notifier = injector.get(ChangeDetectionScheduler);
if (viewContext !== null) {
// This effect was created in the context of a view, and will be associated with the view.
node = createViewEffect(viewContext.view, notifier, effectFn);
if (destroyRef instanceof NodeInjectorDestroyRef && destroyRef._lView === viewContext.view) {
// The effect is being created in the same view as the `DestroyRef` references, so it will be
// automatically destroyed without the need for an explicit `DestroyRef` registration.
destroyRef = null;View on GitHub (pinned to 51cb07e980)
Solutions
- Delete allowSignalWrites from the effect() options - no replacement is needed, writes are always permitted.
- Search the repo for 'allowSignalWrites' and remove every occurrence, including shared effect helper utilities.
- Remove related comments/workarounds explaining the old restriction to prevent re-introduction.
Example fix
// before
effect(() => {
this.count.set(this.count() + 1);
}, {allowSignalWrites: true});
// after
effect(() => {
this.count.set(this.count() + 1);
}); Defensive patterns
Strategy: validation
Validate before calling
// Static check: forbid the flag via lint rule
// ESLint: no-restricted-syntax
{ selector: "Property[key.name='allowSignalWrites']", message: 'allowSignalWrites is a no-op since Angular 19; remove it.' } Prevention
- Search for allowSignalWrites after every major Angular upgrade and delete occurrences.
- Do not copy effect() snippets from pre-Angular-19 docs.
- Signal writes in effects are always permitted now - no opt-in needed.
When it happens
Trigger: Any code like effect(() => { this.count.set(1); }, {allowSignalWrites: true}) - typically left over from Angular 16-18 where the flag was required to write signals inside effects, or inserted defensively by a codemod.
Common situations: Post-upgrade codebases (Angular 19+) that never removed the flag; tutorials and StackOverflow answers predating v19; shared effect-creation utilities that always passed the option.
Related errors
- INITIALIZER_API_DISALLOWED_MEMBER_VISIBILITY
- VALUE_HAS_WRONG_TYPE
- INITIALIZER_API_NO_REQUIRED_FUNCTION
- VALUE_HAS_WRONG_TYPE
- VALUE_NOT_LITERAL
AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22).
Data as JSON: /api/errors/37ed0c45b380d026.
Report an issue: GitHub.