{"record":{"id":"ee49801bf11f281b","repo":"toeverything/AFFiNE","slug":"edgelessexporterror","errorCode":"EdgelessExportError","errorMessage":"Could not find edgeless block component.","messagePattern":"Could not find edgeless block component\\.","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/affine/blocks/root/src/edgeless/clipboard/clipboard.ts","lineNumber":507,"sourceCode":"        boxShadowElements.forEach(function (element) {\n          if (element instanceof HTMLElement) {\n            element.style.setProperty('box-shadow', 'none');\n          }\n        });\n        await replaceImgSrcWithSvg?.(element);\n      },\n      backgroundColor: 'transparent',\n      useCORS: imageProxy ? false : true,\n      proxy: imageProxy,\n    };\n\n    const _drawTopLevelBlock = async (\n      block: GfxBlockElementModel,\n      isInFrame = false\n    ) => {\n      const blockComponent = this.std.view.getBlock(block.id);\n      if (!blockComponent) {\n        throw new BlockSuiteError(\n          ErrorCode.EdgelessExportError,\n          'Could not find edgeless block component.'\n        );\n      }\n\n      const blockBound = Bound.deserialize(block.xywh);\n      const canvasData = await html2canvas(\n        blockComponent as HTMLElement,\n        html2canvasOption\n      );\n      ctx.drawImage(\n        canvasData,\n        blockBound.x - bound.x + padding,\n        blockBound.y - bound.y + padding,\n        blockBound.w,\n        isInFrame\n          ? (blockBound.w / canvasData.width) * canvasData.height\n          : blockBound.h","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/blocksuite/affine/blocks/root/src/edgeless/clipboard/clipboard.ts#L489-L525","documentation":"FrameworkStackProvider layers several providers and resolves each identifier against the first provider in the stack that has it. An empty stack would make every lookup fail with nothing to attribute the failure to, so the constructor rejects an empty providers array immediately rather than producing a permanently broken provider.","triggerScenarios":"new FrameworkStackProvider(providers) where providers was built dynamically (map/filter) and ended up empty; passing [] via a default parameter when a feature flag filtered out every framework; constructing the stack before the list of plugin providers is populated.","commonSituations":"Composing optional plugins where zero are enabled in a minimal build; conditional test setups that skip all providers; refactor moving stack construction above the code that fills the list.","solutions":["Ensure at least one FrameworkProvider is passed — typically the base app framework first, then optional plugin frameworks","Guard before construction: if the dynamic list is empty, fall back to the plain base provider","Fix the upstream filter/map that emptied the list (feature flag disabling every provider, wrong predicate)"],"exampleFix":"// before\nconst providers = enabledPlugins.map(p => p.provider); // [] when all disabled\nconst stack = new FrameworkStackProvider(providers); // throws\n\n// after\nconst providers = [baseProvider, ...enabledPlugins.map(p => p.provider)];\nconst stack = new FrameworkStackProvider(providers);","handlingStrategy":"validation","validationCode":"function createStackProvider(\n  base: FrameworkProvider,\n  extras: FrameworkProvider[]\n): FrameworkProvider {\n  const providers = [base, ...extras].filter(Boolean);\n  if (providers.length === 0) {\n    throw new Error('No providers available: at least the base framework is required');\n  }\n  return providers.length === 1 ? providers[0] : new FrameworkStackProvider(providers);\n}","typeGuard":"null","tryCatchPattern":null,"preventionTips":["Always put the base app provider first when composing a stack from optional plugin providers","Validate dynamically built provider lists for non-emptiness before constructing FrameworkStackProvider","Check feature-flag combinations that can filter every provider out"],"tags":["dependency-injection","provider-stack","invalid-argument"],"backgroundTag":"empty-provider-list","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"}