toeverything/AFFiNE · error · BlockSuiteError

EdgelessExportError

EdgelessExportError

Error message

Could not find edgeless block component.

What it means

FrameworkStackProvider layers several providers and resolves each identifier against the first provider in the stack that has it. An empty stack would make every lookup fail with nothing to attribute the failure to, so the constructor rejects an empty providers array immediately rather than producing a permanently broken provider.

Solutions

  1. Ensure at least one FrameworkProvider is passed — typically the base app framework first, then optional plugin frameworks
  2. Guard before construction: if the dynamic list is empty, fall back to the plain base provider
  3. Fix the upstream filter/map that emptied the list (feature flag disabling every provider, wrong predicate)

Example fix

// before
const providers = enabledPlugins.map(p => p.provider); // [] when all disabled
const stack = new FrameworkStackProvider(providers); // throws

// after
const providers = [baseProvider, ...enabledPlugins.map(p => p.provider)];
const stack = new FrameworkStackProvider(providers);
Defensive patterns

Strategy: validation

Validate before calling

function createStackProvider(
  base: FrameworkProvider,
  extras: FrameworkProvider[]
): FrameworkProvider {
  const providers = [base, ...extras].filter(Boolean);
  if (providers.length === 0) {
    throw new Error('No providers available: at least the base framework is required');
  }
  return providers.length === 1 ? providers[0] : new FrameworkStackProvider(providers);
}

Type guard

null

Prevention

When it happens

Trigger: new FrameworkStackProvider(providers) where providers was built dynamically (map/filter) and ended up empty; passing [] via a default parameter when a feature flag filtered out every framework; constructing the stack before the list of plugin providers is populated.

Common situations: Composing optional plugins where zero are enabled in a minimal build; conditional test setups that skip all providers; refactor moving stack construction above the code that fills the list.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/ee49801bf11f281b. Report an issue: GitHub.

Appendix: source

Thrown at blocksuite/affine/blocks/root/src/edgeless/clipboard/clipboard.ts:507

        boxShadowElements.forEach(function (element) {
          if (element instanceof HTMLElement) {
            element.style.setProperty('box-shadow', 'none');
          }
        });
        await replaceImgSrcWithSvg?.(element);
      },
      backgroundColor: 'transparent',
      useCORS: imageProxy ? false : true,
      proxy: imageProxy,
    };

    const _drawTopLevelBlock = async (
      block: GfxBlockElementModel,
      isInFrame = false
    ) => {
      const blockComponent = this.std.view.getBlock(block.id);
      if (!blockComponent) {
        throw new BlockSuiteError(
          ErrorCode.EdgelessExportError,
          'Could not find edgeless block component.'
        );
      }

      const blockBound = Bound.deserialize(block.xywh);
      const canvasData = await html2canvas(
        blockComponent as HTMLElement,
        html2canvasOption
      );
      ctx.drawImage(
        canvasData,
        blockBound.x - bound.x + padding,
        blockBound.y - bound.y + padding,
        blockBound.w,
        isInFrame
          ? (blockBound.w / canvasData.width) * canvasData.height
          : blockBound.h

View on GitHub (pinned to b4c8548c09)