{"record":{"id":"3c5a002c6c4eacc2","repo":"toeverything/AFFiNE","slug":"errorcode-valuenotexists-3c5a00","errorCode":"ErrorCode.ValueNotExists","errorMessage":"Key is not defined in the StoreExtension","messagePattern":"Key is not defined in the StoreExtension","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/framework/store/src/extension/store-extension.ts","lineNumber":44,"sourceCode":"  constructor(readonly store: Store) {\n    super();\n  }\n\n  /**\n   * Lifecycle hook when the yjs document is loaded.\n   */\n  loaded() {}\n\n  /**\n   * Lifecycle hook when the yjs document is disposed.\n   */\n  disposed() {}\n\n  static readonly [storeExtensionSymbol] = true;\n\n  static override setup(di: Container) {\n    if (!this.key) {\n      throw new BlockSuiteError(\n        ErrorCode.ValueNotExists,\n        'Key is not defined in the StoreExtension'\n      );\n    }\n\n    di.add(this, [StoreIdentifier]);\n    di.addImpl(StoreExtensionIdentifier(this.key), provider =>\n      provider.get(this)\n    );\n  }\n}\n\nexport function isStoreExtensionConstructor(\n  extension: object\n): extension is typeof StoreExtension {\n  return storeExtensionSymbol in extension;\n}\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/blocksuite/framework/store/src/extension/store-extension.ts#L26-L62","documentation":"Thrown by `StoreExtension.setup` when a subclass of `StoreExtension` is being registered but its static `key` property is undefined. The base class declares `static readonly key: string` with no initializer; subclasses MUST override it. The DI container uses this key to expose the extension under `StoreExtensionIdentifier(key)`.","triggerScenarios":"Extending `StoreExtension` (e.g. to build a custom store-level extension) and passing the subclass to the store's extensions list without setting `static override readonly key = 'something'`. The static `setup` runs at store construction and trips the guard.","commonSituations":"Copy-pasting the `StoreExtension` boilerplate and forgetting the key; renaming the key to `undefined`; using a plain `Extension` instead of `StoreExtension` when you actually want store lifecycle hooks.","solutions":["Override the static key on your subclass: `static override readonly key = 'my-extension';`.","Use a unique, stable key (it becomes the DI identifier).","If you do not need store lifecycle hooks, extend `Extension` instead of `StoreExtension`."],"exampleFix":"// before: missing key override\nclass MyExt extends StoreExtension {\n  override loaded() { /* ... */ }\n}\n\n// after: declare a unique static key\nclass MyExt extends StoreExtension {\n  static override readonly key = 'my-ext';\n  override loaded() { /* ... */ }\n}","handlingStrategy":"validation","validationCode":"// verify the subclass declares its key before registering\nfunction extensionHasKey(ext: typeof StoreExtension): boolean {\n  return typeof (ext as any).key === 'string' && (ext as any).key.length > 0;\n}\n\nif (extensionHasKey(MyExt)) storeExtensions.push(MyExt);\nelse throw new Error('StoreExtension subclass must override static key');","typeGuard":"function isKeyedStoreExtension(ext: typeof StoreExtension): ext is typeof StoreExtension & { key: string } {\n  return typeof (ext as any).key === 'string';\n}","tryCatchPattern":"import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';\n\ntry {\n  MyExt.setup(container);\n} catch (e) {\n  if (e instanceof BlockSuiteError && e.code === ErrorCode.ValueNotExists) {\n    console.error('StoreExtension missing static key:', MyExt.name);\n  }\n}","preventionTips":["Always override `static readonly key` on StoreExtension subclasses.","Use a unique, stable key value.","Extend plain Extension if you do not need store lifecycle hooks."],"tags":["store-extension","di","registration","config"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}