toeverything/AFFiNE · error · BlockSuiteError

ValueNotExists

ValueNotExists

Error message

Key is not defined in the EdgelessClipboardConfig

What it means

Thrown by EdgelessClipboardConfig.setup (the static DI registration hook) when the subclass has not defined the static 'key' property. The key is used to build EdgelessClipboardConfigIdentifier(this.key), so an empty/undefined key makes the clipboard config unidentifiable in the DI container. Error code ValueNotExists. This is a developer/registration-time error, not a runtime user error.

Source

Thrown at blocksuite/affine/blocks/surface/src/extensions/clipboard-config.ts:65

    index?: number
  ) => {
    const block = await this.std.clipboard.pasteBlockSnapshot(
      snapshot,
      doc,
      parent,
      index
    );
    return block?.id ?? null;
  };

  abstract createBlock(
    snapshot: BlockSnapshot,
    context: ClipboardConfigCreationContext
  ): string | null | Promise<string | null>;

  static override setup(di: Container) {
    if (!this.key) {
      throw new BlockSuiteError(
        BlockSuiteError.ErrorCode.ValueNotExists,
        'Key is not defined in the EdgelessClipboardConfig'
      );
    }

    di.add(
      this as unknown as { new (std: BlockStdScope): EdgelessClipboardConfig },
      [StdIdentifier]
    );

    di.addImpl(EdgelessClipboardConfigIdentifier(this.key), provider =>
      provider.get(this)
    );
  }
}

View on GitHub (pinned to 26c515e050)

Solutions

  1. Declare a unique static key on every EdgelessClipboardConfig subclass: `static override key = 'affine:my-block-clipboard';`.
  2. Use a stable, namespaced string so the identifier round-trips consistently across versions.
  3. Add a unit test that imports each config subclass and asserts typeof Subclass.key === 'string' && Subclass.key.length > 0.

Example fix

// before
class MyBlockClipboard extends EdgelessClipboardConfig {
  // no static key -> setup throws ValueNotExists
  createBlock(...) { ... }
}

// after
class MyBlockClipboard extends EdgelessClipboardConfig {
  static override key = 'affine:my-block-clipboard';
  createBlock(...) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

import { EdgelessClipboardConfig } from '@blocksuite/affine-block-surface';
// assert at module load / in a test:
if (typeof MyClipboardConfig.key !== 'string' || !MyClipboardConfig.key) {
  throw new Error('MyClipboardConfig must define static key');
}

Type guard

function hasClipboardKey(Ctor) {
  return typeof Ctor.key === 'string' && Ctor.key.length > 0;
}

Prevention

When it happens

Trigger: Creating a subclass of EdgelessClipboardConfig (a custom clipboard behaviour for an edgeless block flavour) and registering it via the framework without declaring `static key: string = '...'`. The error fires when the extension system calls setup(di) during editor initialisation.

Common situations: Authoring a new edgeless block with custom paste behaviour and forgetting the static key; refactor that renames/removes the key field; copy-paste of an existing config subclass minus the key declaration.

Related errors


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