toeverything/AFFiNE · error · RecursionLimitError
Dynamic resolve recursion limit reached
Error message
Dynamic resolve recursion limit reached
What it means
track() increments a depth counter while resolving service identifiers; when resolution nesting reaches 100 levels it assumes a runaway/circular dependency graph and throws RecursionLimitError. Called from nextResolver during dependency resolution.
Source
Thrown at packages/common/infra/src/framework/core/provider.ts:269
} else {
service = this.provider.cache.getOrInsert(
{
identifierName: identifier.identifierName,
variant,
},
runFactory
);
}
result.set(variant, service);
}
return result;
}
track(identifier: IdentifierValue): Resolver {
const depth = this.depth + 1;
if (depth >= 100) {
throw new RecursionLimitError();
}
const circular = this.stack.find(
i =>
i.identifierName === identifier.identifierName &&
i.variant === identifier.variant
);
if (circular) {
throw new CircularDependencyError([...this.stack, identifier]);
}
return new Resolver(this.provider, depth, [...this.stack, identifier]);
}
override dispose(): void {}
}
export class BasicFrameworkProvider extends FrameworkProvider {
public readonly cache = new ComponentCachePool();View on GitHub (pinned to b4c8548c09)
Solutions
- Reduce dynamic resolution depth; a factory likely resolves itself or loops.
- Break the recursive resolution by restructuring the factory or caching the result.
- Inspect the dependency graph for a cycle expressed through dynamic factories.
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at packages/common/infra/src/framework/core/provider.ts:269 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/cc87be61fe987d5e.
Report an issue: GitHub.