toeverything/AFFiNE · error · BlockSuiteError
ValueNotExists
ValueNotExists
Error message
Failed to create portal root
What it means
For non-document tables the validator strictly rejects any data key that is not declared in table.schema — persisting undeclared fields would silently diverge from the persisted shape, and the adapters only store what the schema knows. Document tables (isDocumentTable) are exempt because they accept open shapes; regular tables fail with the offending key named.
Solutions
- Add the field to the table schema if it should be persisted
- Otherwise strip undeclared keys before the write: keep only Object.keys(table.schema)
- If open shapes are intended, use a document table instead of a regular table
Example fix
// before
table.insert({ data: { id: 'a1', name: 'x', tempFlag: true } }); // tempFlag not in schema
// after
// option A: persist it -> add to schema: tempFlag: { type: 'boolean' }
// option B: strip before write:
const data = Object.fromEntries(
Object.entries(entity).filter(([k]) => k in table.schema)
);
table.insert({ data }); Defensive patterns
Strategy: validation
Validate before calling
function pickSchemaFields(data: Record<string, any>, schema: Record<string, unknown>) {
return Object.fromEntries(Object.entries(data).filter(([key]) => key in schema));
}
table.insert({ data: pickSchemaFields(entity, table.schema) }); Type guard
null
Prevention
- Do not reuse DTOs as entities — strip transport-only fields before writing
- When adding a field to TypeScript types, add it to the table schema in the same change
- Use a document table when open shapes are intended; regular tables enforce closed schemas
When it happens
Trigger: Inserting { id, name, tempFlag } when tempFlag was never added to the schema; renaming a field in code but not in the schema; computed/derived properties left on the object before insert; spreading a DTO (with transport-only fields) directly as entity data.
Common situations: Schema migration added the field to TypeScript types but not the table definition; reusing API DTOs as entities; newer client writing to an older schema.
Related errors
- A curve must have at least three points.
- Bad segment
- Path data ended short
- Param not a number
- ValueNotExists
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/b8799bfa46e660ed.
Report an issue: GitHub.
Appendix: source
Thrown at blocksuite/affine/components/src/portal/helper.ts:44
identifyWrapper = true,
}: PortalOptions) {
const portalRoot = document.createElement('div');
if (identifyWrapper) {
portalRoot.classList.add('blocksuite-portal');
}
if (shadowDom) {
portalRoot.attachShadow({
mode: 'open',
...(typeof shadowDom !== 'boolean' ? shadowDom : {}),
});
}
signal.addEventListener('abort', () => {
portalRoot.remove();
});
const root = shadowDom ? portalRoot.shadowRoot : portalRoot;
if (!root) {
throw new BlockSuiteError(
BlockSuiteError.ErrorCode.ValueNotExists,
'Failed to create portal root'
);
}
let updateId = 0;
const updatePortal: (id: number) => void = id => {
if (id !== updateId) {
console.warn(
'Potentially infinite recursion! Please clean up the old event listeners before `updatePortal`'
);
return;
}
updateId++;
const curId = updateId;
const templateResult =
template instanceof Function
? template({ updatePortal: () => updatePortal(curId) })View on GitHub (pinned to b4c8548c09)