{"record":{"id":"24a6f0233876db0d","repo":"toeverything/AFFiNE","slug":"errorcode-missingviewmodelerror","errorCode":"ErrorCode.MissingViewModelError","errorMessage":"Cannot find block model for id ${this.blockId}","messagePattern":"Cannot find block model for id (.+?)","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/framework/std/src/view/element/block-component.ts","lineNumber":114,"sourceCode":"    const expectedVersion = schema.version;\n    const actualVersion = this.model.version;\n    if (expectedVersion !== actualVersion) {\n      console.warn(\n        `Version mismatch for block ${this.model.id}, expected ${expectedVersion}, actual ${actualVersion}`\n      );\n      return true;\n    }\n\n    return false;\n  }\n\n  get model() {\n    if (this._model) {\n      return this._model;\n    }\n    const model = this.store.getModelById<Model>(this.blockId);\n    if (!model) {\n      throw new BlockSuiteError(\n        ErrorCode.MissingViewModelError,\n        `Cannot find block model for id ${this.blockId}`\n      );\n    }\n    this._model = model;\n    return model;\n  }\n\n  get parentComponent(): BlockComponent | null {\n    const parent = this.model.parent;\n    if (!parent) return null;\n    return this.std.view.getBlock(parent.id);\n  }\n\n  get renderChildren() {\n    return this.host.renderChildren.bind(this);\n  }\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/blocksuite/framework/std/src/view/element/block-component.ts#L96-L132","documentation":"Thrown by the `BlockComponent.model` getter (block-component.ts) when `this.store.getModelById(this.blockId)` returns undefined. The component is bound to a `blockId` that does not exist in the store — either it was never created, was deleted, or the store has not loaded it yet. The result is cached, so the lookup happens once per component instance.","triggerScenarios":"Rendering a `<block-component blockId=\"...\">` whose id is not present in the store: stale id left in a template after the block was deleted; store still loading asynchronously; id typo; wrong store instance passed to the host.","commonSituations":"Listing child models then rendering them while a collaborative delete removes one mid-render; SSR with an empty store; passing a `blockId` from one doc into a host bound to another doc; reading `model` in `connectedCallback` before `doc.loaded`.","solutions":["Wait for `store.loaded` (the doc loaded signal/promise) before rendering block components.","Filter rendered ids through `store.getModelById` first and drop missing ones.","Re-derive `blockId` lists reactively from the model tree rather than caching stale ids.","Confirm the same `store` instance is shared by the host and the component."],"exampleFix":"// before: rendering possibly-stale ids\nhtml`${repeat(ids, id => id, id => html`<block-component blockId=${id}></block-component>`)}`\n\n// after: filter to ids that still exist\nhtml`${repeat(ids.filter(id => store.getModelById(id)), id => id, id => html`<block-component blockId=${id}></block-component>`)}`","handlingStrategy":"validation","validationCode":"// filter block ids through the store before rendering\nfunction existingBlockIds(store: Store, ids: string[]): string[] {\n  return ids.filter(id => !!store.getModelById(id));\n}\n\nconst liveIds = existingBlockIds(store, ids);\nrender(html`${repeat(liveIds, id => id, id => html`<block-component blockId=${id}></block-component>`)}`, container);","typeGuard":"function blockExists(store: Store, id: string): boolean {\n  return !!store.getModelById(id);\n}","tryCatchPattern":"import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';\n\nlet model: Model;\ntry {\n  model = blockComponent.model;\n} catch (e) {\n  if (e instanceof BlockSuiteError && e.code === ErrorCode.MissingViewModelError) {\n    // block was deleted; skip rendering\n    return;\n  }\n  throw e;\n}","preventionTips":["Derive block id lists reactively from the model tree rather than caching them.","Wait for `store.loaded` before rendering block components.","Confirm the same store instance is shared by host and component."],"tags":["block-component","store","model","lifecycle"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}