{"record":{"id":"02552b150ce4934e","repo":"toeverything/AFFiNE","slug":"transformernotimplementederror","errorCode":"TransformerNotImplementedError","errorMessage":"NotionHtmlAdapter.fromBlockSnapshot is not implemented","messagePattern":"NotionHtmlAdapter\\.fromBlockSnapshot is not implemented","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"warning","filePath":"blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts","lineNumber":141,"sourceCode":"    const notionHtmlInlineToDeltaMatchers = Array.from(\n      provider.getAll(NotionHtmlASTToDeltaMatcherIdentifier).values()\n    );\n    this.blockMatchers = blockMatchers;\n    this.deltaConverter = new NotionHtmlDeltaConverter(\n      job.adapterConfigs,\n      [],\n      notionHtmlInlineToDeltaMatchers\n    );\n  }\n\n  private _htmlToAst(notionHtml: NotionHtml) {\n    return unified().use(rehypeParse).parse(notionHtml);\n  }\n\n  override fromBlockSnapshot(\n    _payload: FromBlockSnapshotPayload\n  ): Promise<FromBlockSnapshotResult<NotionHtml>> {\n    throw new BlockSuiteError(\n      ErrorCode.TransformerNotImplementedError,\n      'NotionHtmlAdapter.fromBlockSnapshot is not implemented'\n    );\n  }\n\n  override fromDocSnapshot(\n    _payload: FromDocSnapshotPayload\n  ): Promise<FromDocSnapshotResult<NotionHtml>> {\n    throw new BlockSuiteError(\n      ErrorCode.TransformerNotImplementedError,\n      'NotionHtmlAdapter.fromDocSnapshot is not implemented'\n    );\n  }\n\n  override fromSliceSnapshot(\n    _payload: FromSliceSnapshotPayload\n  ): Promise<FromSliceSnapshotResult<NotionHtml>> {\n    throw new BlockSuiteError(","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts#L123-L159","documentation":"NotionHtmlAdapter (affine/shared/src/adapters/notion-html/notion-html.ts:144-149) is an import-only adapter: it implements toBlockSnapshot (Notion HTML -> block snapshot). The export direction fromBlockSnapshot is deliberately unimplemented and throws TransformerNotImplementedError whenever called.","triggerScenarios":"Running a block-snapshot -> Notion HTML export (e.g. Transformer job that iterates adapters and calls fromBlockSnapshot on every registered adapter); explicitly invoking NotionHtmlAdapter.get().fromBlockSnapshot(payload).","commonSituations":"Copy/paste or export pipelines that query all registered adapters generically; a user's clipboard containing Notion HTML triggers toBlockSnapshot (fine), but an export-to-Notion-HTML feature would hit this; code assuming every Adapter implements all six methods.","solutions":["Do not use NotionHtmlAdapter for export; use an adapter that implements fromBlockSnapshot (e.g. MarkdownAdapter/HtmlAdapter) for doc->output","Catch TransformerNotImplementedError in generic adapter loops and skip the adapter","Check adapter capabilities before calling (this adapter only supports toBlockSnapshot)"],"exampleFix":"// before\nconst html = await adapter.fromBlockSnapshot({ snapshot, assets }); // throws\n\n// after\nif (adapter instanceof NotionHtmlAdapter) {\n  throw new Error('Export to Notion HTML is not supported');\n}\nconst md = await markdownAdapter.fromBlockSnapshot({ snapshot, assets });","handlingStrategy":"try-catch","validationCode":"import { NotionHtmlAdapter } from '@blocksuite/affine/shared/adapters/notion-html';\n\n// only use the supported direction\nconst supportsFromBlockSnapshot = (adapter: unknown): boolean =>\n  !(adapter instanceof NotionHtmlAdapter); // this adapter is toBlockSnapshot-only","typeGuard":"function isImportOnlyAdapter(adapter: Adapter): boolean {\n  return adapter instanceof NotionHtmlAdapter;\n}","tryCatchPattern":"import { BlockSuiteError } from '@blocksuite/global/exceptions';\n\ntry {\n  const output = await adapter.fromBlockSnapshot(payload);\n} catch (e) {\n  if (e instanceof BlockSuiteError && e.code === BlockSuiteError.ErrorCode.TransformerNotImplementedError) {\n    // adapter cannot export; skip it or pick another adapter\n    continue;\n  }\n  throw e;\n}","preventionTips":["Register NotionHtmlAdapter only for import pipelines, never in export adapter lists","In generic adapter loops, skip adapters whose from* methods are stubs","Model adapter capabilities explicitly instead of probing by exception"],"tags":["adapter","transformer","notion","import-export","not-implemented"],"backgroundTag":"not-implemented","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}