toeverything/AFFiNE · error · BlockSuiteError

ValueNotExists

ValueNotExists

Error message

EmbedIframeService or LinkPreviewService not found

What it means

Thrown by EmbedIframeBlockComponent.refreshData when either EmbedIframeService or LinkPreviewService is not resolvable from the std dependency-injection container (this.std.get(...) returned undefined). These services are optional DI providers; the embed-iframe block cannot fetch embed or link-preview metadata without them. The whole refresh is wrapped in try/catch and surfaces as status$='error', so the throw is converted to a user-facing error state rather than a crash.

Source

Thrown at blocksuite/affine/blocks/embed/src/embed-iframe-block/embed-iframe-block.ts:163

  };

  refreshData = async () => {
    try {
      const { url } = this.model.props;
      if (!url) {
        this.status$.value = 'idle';
        return false;
      }

      // set loading status
      this.status$.value = 'loading';
      this.error$.value = null;

      // get embed data
      const embedIframeService = this.embedIframeService;
      const linkPreviewService = this.linkPreviewService;
      if (!embedIframeService || !linkPreviewService) {
        throw new BlockSuiteError(
          ErrorCode.ValueNotExists,
          'EmbedIframeService or LinkPreviewService not found'
        );
      }

      // get embed data and preview data in a promise
      const [embedData, previewData] = await Promise.all([
        embedIframeService.getEmbedIframeData(url),
        linkPreviewService.query(url),
      ]);

      // if the embed data is not found, and the iframeUrl is not set, throw an error
      const currentIframeUrl = this.model.props.iframeUrl;
      if (!embedData && !currentIframeUrl) {
        throw new BlockSuiteError(
          ErrorCode.ValueNotExists,
          'Failed to get embed data'
        );

View on GitHub (pinned to 26c515e050)

Solutions

  1. Register EmbedIframeService and a LinkPreviewService implementation in your editor's std extensions before mounting the embed-iframe block.
  2. If link preview is intentionally unavailable, provide a no-op LinkPreviewService so the dependency resolves (query returns null) and only embed data is required downstream.
  3. Subscribe to embedIframeBlock.status$ / error$ to surface the missing-service state to users instead of silently failing.

Example fix

// before
// EmbedIframeService not registered -> refreshData throws ValueNotExists

// after
import { EmbedIframeService } from '@blocksuite/affine-shared/services';
stdBuilder.add(EmbedIframeService, /* link preview provider */);
Defensive patterns

Strategy: validation

Validate before calling

const embed = std.get(EmbedIframeService);
const link = std.get(LinkPreviewServiceIdentifier);
const ready = !!embed && !!link;
// only call refreshData when ready, else register the services first

Type guard

function hasEmbedServices(std) {
  return !!std.get(EmbedIframeService) && !!std.get(LinkPreviewServiceIdentifier);
}

Try / catch

embedIframeBlock.status$.subscribe(s => {
  if (s === 'error' && embedIframeBlock.error$.value?.message.includes('not found')) {
    // prompt user: embed services unavailable in this editor
  }
});

Prevention

When it happens

Trigger: Calling embedIframeBlock.refreshData() (or any flow that triggers it, such as pasting a link or pressing refresh) in an editor setup where EmbedIframeService and/or LinkPreviewServiceIdentifier were never registered with the std DI container. Common when embedding the block in a custom/lightweight editor flavour that omits the embed-service extensions.

Common situations: Custom integrations that mount only a subset of BlockSuite extensions; tree-shaking or feature-flag configurations that drop the embed-iframe services; upgrades where the service identifier token changed but the registration was not updated.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/b82554e20730244b. Report an issue: GitHub.