Claude generates this anti-pattern due to shallow pattern matching across incompatible mental models:
Every getter access creates a new computed signal with fresh subscriptions:
obj.fullName; // Creates computed signal #1
obj.fullName; // Creates computed signal #2 (never cleaned up!)This causes:
- Memory leaks (subscriptions never disposed)
- Lost reactivity (each call returns different signal instance)
- Performance degradation (recomputing from scratch every access)
1. Conflating React patterns with Signals
- React: getters compute on-demand (no subscriptions)
- Signals:
computed()creates persistent reactive state
2. Missing the object lifecycle
computed() returns a Signal object that needs storage, not a pure computation. Claude sees:
- "Computed values" → thinks getters
computed()syntax → thinks wrapper function- Doesn't connect: "this creates a stateful subscription graph"
3. Syntactic rather than semantic understanding Combines two patterns without understanding the execution model:
- Pattern A:
get foo()for derived values - Pattern B:
computed(() => ...)for reactivity - Fails to see: Pattern B creates objects that need storage
class Foo {
// ✓ Property: store the computed signal
fullName = computed(() => `${this.first.value} ${this.last.value}`);
// ✓ Getter: return .value of stored computed
private _fullName = computed(() => `${this.first.value} ${this.last.value}`);
get fullName() {
return this._fullName.value;
}
}The core issue: Claude doesn't model that computed() has side effects (creates subscriptions) and returns stateful objects, not pure functions.