{"record":{"id":"7dec54f7d5fdd99a","repo":"toeverything/AFFiNE","slug":"errorcode-gfxblockelementerror","errorCode":"ErrorCode.GfxBlockElementError","errorMessage":"Error on rendering '${this.model.flavour}': Gfx block's model should have 'xywh' property.","messagePattern":"Error on rendering '(.+?)': Gfx block's model should have 'xywh' property\\.","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/framework/std/src/view/element/gfx-block-component.ts","lineNumber":162,"sourceCode":"\n  getCSSTransform() {\n    const viewport = this.gfx.viewport;\n    const { translateX, translateY, zoom, viewScale } = viewport;\n    const bound = Bound.deserialize(this.model.xywh);\n\n    const scaledX = (bound.x * zoom) / viewScale;\n    const scaledY = (bound.y * zoom) / viewScale;\n    const deltaX = scaledX - bound.x;\n    const deltaY = scaledY - bound.y;\n\n    return `translate(${translateX / viewScale + deltaX}px, ${translateY / viewScale + deltaY}px) scale(${this.getCSSScaleVal()})`;\n  }\n\n  getRenderingRect() {\n    const { xywh$ } = this.model;\n\n    if (!xywh$) {\n      throw new BlockSuiteError(\n        ErrorCode.GfxBlockElementError,\n        `Error on rendering '${this.model.flavour}': Gfx block's model should have 'xywh' property.`\n      );\n    }\n\n    const [x, y, w, h] = JSON.parse(xywh$.value);\n\n    return { x, y, w, h, zIndex: this.toZIndex() };\n  }\n\n  override renderBlock() {\n    const { x, y, w, h, zIndex } = this.getRenderingRect();\n\n    if (this.style.left !== `${x}px`) this.style.left = `${x}px`;\n    if (this.style.top !== `${y}px`) this.style.top = `${y}px`;\n    if (this.style.width !== `${w}px`) this.style.width = `${w}px`;\n    if (this.style.height !== `${h}px`) this.style.height = `${h}px`;\n    if (this.style.zIndex !== zIndex) this.style.zIndex = zIndex;","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/blocksuite/framework/std/src/view/element/gfx-block-component.ts#L144-L180","documentation":"GfxBlockElement.getRenderingRect() (gfx-block-component.ts) computes the element's geometry from the model's reactive xywh$ signal; a gfx (surface/edgeless) block without an 'xywh' string prop cannot be positioned, so rendering aborts with GfxBlockElementError. The flavour named in the message is the block whose schema or instance lacks xywh.","triggerScenarios":"Rendering a block flavour in the edgeless/gfx context whose schema does not define an xywh: z.string() prop, or whose model instance never received an xywh value (created via doc.addBlock without xywh, or imported from a snapshot missing it).","commonSituations":"Writing a custom edgeless block and forgetting the xywh prop in the FlavourDefine/schema; creating blocks with doc.addBlock({flavour:'affine:embed-...'}) without xywh; importing third-party snapshots that omit xywh; reusing a doc block flavour on the surface without adaptation.","solutions":["Add xywh to the flavour's props schema (props: { xywh: z.string().optional()... } per BlockSchemaDefinition) and always pass a '[x,y,w,h]' JSON string on creation.","When inserting into edgeless, use the surface/gfx insert APIs that compute xywh for you.","Repair existing docs by backfilling a default xywh for models missing it before render.","If the block is not meant for edgeless, render it in doc mode / don't mount it under the gfx container."],"exampleFix":"// before\nconst MyBlockSchema = defineBlockSchema({\n  flavour: 'my:block',\n  props: => ({ text: z.string() }), // no xywh\n});\ndoc.addBlock('my:block', {}, surfaceId);\n\n// after\nprops: => ({ text: z.string(), xywh: z.string() }),\ndoc.addBlock('my:block', { xywh: '[0,0,200,80]' }, surfaceId);","handlingStrategy":"validation","validationCode":"const model = doc.getModelById(id);\nif (model && typeof model.xywh === 'string') {\n  // safe to render in edgeless/gfx context\n} else {\n  doc.addBlock? doc.updateBlock(model, { xywh: '[0,0,200,80]' }); // backfill before render\n}","typeGuard":"function hasXywh(model: { xywh?: unknown }): boolean {\n  return typeof model.xywh === 'string' && model.xywh.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always include xywh: z.string() in custom edgeless block schemas.","Create surface blocks through the edgeless insert APIs that compute xywh from coordinates.","Backfill xywh for imported/migrated models before mounting the gfx view."],"tags":["blocksuite","edgeless","gfx","block-schema","missing-prop"],"backgroundTag":"missing-required-model-prop","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}