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

  1. Validate before calling: only build the filter if vars.some(v => v.id === ref.name) and getRefType returns a type
  2. Repair saved filters on load: remove or rebuild filters whose left.name is absent from the current variable ids
  3. When deleting a column, also delete filters (and sorts/group-bys) that reference it
  4. 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 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)