{"record":{"id":"6c8efc28bf236a5b","repo":"toeverything/AFFiNE","slug":"valuenotexists-6c8efc","errorCode":"ValueNotExists","errorMessage":"The overlay constructor '${this.name}' should have a static 'overlayName' property.","messagePattern":"The overlay constructor '(.+?)' should have a static 'overlayName' property\\.","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/affine/blocks/surface/src/renderer/overlay.ts","lineNumber":27,"sourceCode":"import type { RoughCanvas } from '../utils/rough/canvas.js';\nimport type { CanvasRenderer } from './canvas-renderer.js';\n\n/**\n * An overlay is a layer covered on top of elements,\n * can be used for rendering non-CRDT state indicators.\n */\nexport abstract class Overlay extends Extension {\n  static overlayName: string = '';\n\n  protected _renderer: CanvasRenderer | null = null;\n\n  constructor(protected gfx: GfxController) {\n    super();\n  }\n\n  static override setup(di: Container): void {\n    if (!this.overlayName) {\n      throw new BlockSuiteError(\n        ErrorCode.ValueNotExists,\n        `The overlay constructor '${this.name}' should have a static 'overlayName' property.`\n      );\n    }\n\n    di.addImpl(OverlayIdentifier(this.overlayName), this, [\n      GfxControllerIdentifier,\n    ]);\n  }\n\n  clear() {\n    this.refresh();\n  }\n\n  dispose() {}\n\n  refresh() {\n    if (this._renderer) {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/blocksuite/affine/blocks/surface/src/renderer/overlay.ts#L9-L45","documentation":"Thrown by Overlay.setup (static DI hook) when the Overlay subclass has not overridden the static 'overlayName' property (it defaults to ''). The overlayName is used to build OverlayIdentifier(this.overlayName) for DI resolution; an empty name makes the overlay unidentifiable. Error code ValueNotExists. This is a registration-time developer error, raised during editor extension setup.","triggerScenarios":"Authoring a custom Overlay subclass (a canvas layer drawn on top of elements, e.g. selection handles, alignment guides) and registering it without setting `static overlayName = '...'`. The framework calls setup(di) at init and throws.","commonSituations":"New overlay written by following an example that omitted overlayName; refactor that moved the field; subclassing Overlay indirectly and forgetting the static field; collision-free naming not enforced so a developer skips it.","solutions":["Declare a unique static overlayName on every Overlay subclass: `static override overlayName = 'my-overlay';`.","Add a compile-time/test check that imports each Overlay subclass and asserts Subclass.overlayName is a non-empty string.","Names are DI keys — keep them stable across versions and avoid collisions with built-in overlays."],"exampleFix":"// before\nclass MyOverlay extends Overlay {\n  // no overlayName -> setup throws ValueNotExists\n  render(ctx, rc) { ... }\n}\n\n// after\nclass MyOverlay extends Overlay {\n  static override overlayName = 'my-overlay';\n  render(ctx, rc) { ... }\n}","handlingStrategy":"validation","validationCode":"import { Overlay } from '@blocksuite/affine-block-surface';\n// assert at module load / in a test:\nif (typeof MyOverlay.overlayName !== 'string' || !MyOverlay.overlayName) {\n  throw new Error('MyOverlay must define static overlayName');\n}","typeGuard":"function hasOverlayName(Ctor) {\n  return typeof Ctor.overlayName === 'string' && Ctor.overlayName.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always declare `static override overlayName = '...'` on Overlay subclasses.","Keep overlayName stable and collision-free across versions.","Add a unit test asserting each Overlay subclass has a non-empty static overlayName."],"tags":["overlay","renderer","dependency-injection","registration"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}