toeverything/AFFiNE · error · BlockSuiteError
DatabaseBlockError
DatabaseBlockError
Error message
can't resolve ref type
What it means
Thrown by firstFilterName (blocksuite/affine/data-view/src/core/filter/utils.ts:11) when getRefType(vars, ref) returns undefined. A filter's left-hand VariableRef must resolve to a Variable in the passed vars list; if no variable matches ref.name (a column id), the type cannot be determined and DatabaseBlockError 'can't resolve ref type' is thrown. It signals a filter expression referencing a column that is not in the current variable set.
Solutions
- Validate before calling: only build the filter if vars.some(v => v.id === ref.name) and getRefType returns a type
- Repair saved filters on load: remove or rebuild filters whose left.name is absent from the current variable ids
- When deleting a column, also delete filters (and sorts/group-bys) that reference it
- Catch the error and rebuild with firstFilter(vars) against an existing column
Example fix
// before
const filter = firstFilterByRef(vars, { type: 'ref', name: deletedColumnId }); // throws
// after
if (!vars.some(v => v.id === ref.name)) {
// rebuild against an existing column instead of throwing
return firstFilter(vars);
} Defensive patterns
Strategy: validation
Validate before calling
import { getRefType } from '../expression/ref/ref.js';
const isRefResolvable = (vars: Variable[], ref: VariableRef): boolean =>
vars.some(v => v.id === ref.name) && !!getRefType(vars, ref); Type guard
const isResolvableRef = (vars: Variable[]): ((ref: VariableRef) => boolean) => ref => vars.some(v => v.id === ref.name);
Try / catch
try {
const filter = firstFilterByRef(vars, ref);
} catch (e) {
if (e instanceof BlockSuiteError && e.code === BlockSuiteError.ErrorCode.DatabaseBlockError) {
// referenced column is gone: rebuild a default filter from remaining vars
return firstFilter(vars);
}
throw e;
} Prevention
- When deleting a column, delete filters referencing it in the same update
- Validate saved filter JSON against current column ids on load
- Never pass a subsetted vars array that excludes the ref target
When it happens
Trigger: Calling firstFilterName or firstFilterByRef with a ref whose name is a deleted column id; passing a filtered/subset vars array that excludes the referenced column; deserializing saved filter JSON whose left.name no longer matches any dataSource property id.
Common situations: Loading a saved view whose filter references a column deleted later; copying filter config between databases with different schemas; column deletion racing the filter menu re-render.
Related errors
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/505c6f60b9795c5a.
Report an issue: GitHub.
Appendix: source
Thrown at blocksuite/affine/data-view/src/core/filter/utils.ts:11
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { getRefType } from '../expression/ref/ref.js';
import type { Variable, VariableRef } from '../expression/types.js';
import { filterMatcher } from './filter-fn/matcher.js';
import type { FilterGroup, SingleFilter } from './types.js';
export const firstFilterName = (vars: Variable[], ref: VariableRef) => {
const type = getRefType(vars, ref);
if (!type) {
throw new BlockSuiteError(
ErrorCode.DatabaseBlockError,
`can't resolve ref type`
);
}
return filterMatcher.firstMatchedBySelfType(type)?.name;
};
export const firstFilterByRef = (
vars: Variable[],
ref: VariableRef
): SingleFilter => {
return {
type: 'filter',
left: ref,
function: firstFilterName(vars, ref),
args: [],
};
};
export const firstFilter = (vars: Variable[]): SingleFilter => {View on GitHub (pinned to b4c8548c09)