toeverything/AFFiNE · error · BlockSuiteError
ValueNotExists
ValueNotExists
Error message
property ${propertyId} not found What it means
The base Component class (parent of Service, Store, Entity, Scope) gets its framework provider and props from a module-level CONSTRUCTOR_CONTEXT that is only populated while the DI container runs a component factory (via withContext). Constructing any Component subclass outside that synchronous window leaves CONSTRUCTOR_CONTEXT.current.provider undefined, so the constructor aborts immediately. This guarantees every component is born with a backing provider (framework, eventBus, DI) instead of existing half-initialized.
Solutions
- Never instantiate Component subclasses yourself: register with framework.service(MyService, [Deps]) / framework.impl(Identifier, MyService) and obtain instances via provider.get(MyService), provider.createEntity(...)
- When registering with a custom factory, accept the resolver argument and resolve dependencies inside it; better, pass the class + deps array so dependenciesToFactory constructs it within provider context
- In tests, build a minimal Framework (new Framework()), register the unit under test plus its dependencies, and instantiate through framework.provider().get(...)
Example fix
// before const s = new MyService(dep); // throws: no provider context // after const fw = new Framework(); fw.service(MyService, [MyDep]); // container constructs it in context const s = fw.provider().get(MyService);
Defensive patterns
Strategy: validation
Validate before calling
null
Type guard
null
Prevention
- Treat Component/Service/Store/Entity constructors as container-private: never call new on them in app code
- Register classes with their dependency arrays (framework.service/impl) so the container constructs them inside withContext
- In custom factories passed to impl(), accept the resolver parameter and let the container invoke the factory
- In tests, spin up a minimal Framework and resolve through framework.provider().get(...) instead of direct construction
When it happens
Trigger: Calling `new MyService(...)` directly in app code or tests; writing a custom factory like `framework.impl(Identifier, () => new MyService())` — a plain arrow factory runs outside withContext; constructing a Component subclass inside an async continuation (Promise.then) that escaped the factory call.
Common situations: Unit tests that construct services manually to skip Framework setup; refactoring a POJO that was previously `new`-ed into a Component subclass; passing a hand-written factory function to impl() instead of the class plus deps array, so the container never wraps construction in context.
Related errors
- DatabaseBlockError
- EdgelessExportError
- ErrorCode.DefaultRuntimeError
- Failed to read image size
- GfxBlockElementError
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/d5168bc2b5decfaa.
Report an issue: GitHub.
Appendix: source
Thrown at blocksuite/affine/blocks/data-view/src/data-source.ts:104
this.workspace.slots.docListUpdated.subscribe(() => {
this.workspace.docs.forEach(doc => {
if (!this.docDisposeMap.has(doc.id)) {
this.listenToDoc(doc.getStore());
}
});
this.docDisposeMap.forEach((_, id) => {
if (!this.workspace.docs.has(id)) {
this.docDisposeMap.get(id)?.();
this.docDisposeMap.delete(id);
}
});
});
}
private getProperty(propertyId: string) {
const property = this.meta.properties.find(v => v.key === propertyId);
if (!property) {
throw new BlockSuiteError(
BlockSuiteError.ErrorCode.ValueNotExists,
`property ${propertyId} not found`
);
}
return property;
}
private newColumnName() {
let i = 1;
while (
this.block.props.columns.some(column => column.name === `Column ${i}`)
) {
i++;
}
return `Column ${i}`;
}
cellValueChange(rowId: string, propertyId: string, value: unknown): void {View on GitHub (pinned to b4c8548c09)