From 0444e03478a47d57cc151010e9f324b695d65a71 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Fri, 28 Nov 2025 03:28:11 -0800 Subject: [PATCH 1/3] Guard node help fetch from HTML and skip blueprint docs --- src/services/nodeHelpService.ts | 51 +++++++++++++++++++++-------- src/workbench/utils/nodeHelpUtil.ts | 3 ++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/services/nodeHelpService.ts b/src/services/nodeHelpService.ts index 88bb48d29b2..9c15a09c5dd 100644 --- a/src/services/nodeHelpService.ts +++ b/src/services/nodeHelpService.ts @@ -7,6 +7,10 @@ class NodeHelpService { async fetchNodeHelp(node: ComfyNodeDefImpl, locale: string): Promise { const nodeSource = getNodeSource(node.python_module) + if (nodeSource.type === NodeSourceType.Blueprint) { + return node.description || '' + } + if (nodeSource.type === NodeSourceType.CustomNodes) { return this.fetchCustomNodeHelp(node, locale) } else { @@ -25,19 +29,15 @@ class NodeHelpService { // Try locale-specific path first const localePath = `/extensions/${customNodeName}/docs/${node.name}/${locale}.md` - let res = await fetch(api.fileURL(localePath)) + const localeDoc = await this.tryFetchMarkdown(localePath) + if (localeDoc) return localeDoc - if (!res.ok) { - // Fall back to non-locale path - const fallbackPath = `/extensions/${customNodeName}/docs/${node.name}.md` - res = await fetch(api.fileURL(fallbackPath)) - } - - if (!res.ok) { - throw new Error(res.statusText) - } + // Fall back to non-locale path + const fallbackPath = `/extensions/${customNodeName}/docs/${node.name}.md` + const fallbackDoc = await this.tryFetchMarkdown(fallbackPath) + if (fallbackDoc) return fallbackDoc - return res.text() + throw new Error('Help not found') } private async fetchCoreNodeHelp( @@ -45,13 +45,36 @@ class NodeHelpService { locale: string ): Promise { const mdUrl = `/docs/${node.name}/${locale}.md` - const res = await fetch(api.fileURL(mdUrl)) + const doc = await this.tryFetchMarkdown(mdUrl) + if (!doc) { + throw new Error('Help not found') + } + + return doc + } + + /** + * Fetch a markdown file and return its text, guarding against HTML/SPA fallbacks. + * Returns null when not OK or when the content looks like HTML. + */ + private async tryFetchMarkdown(path: string): Promise { + const res = await fetch(api.fileURL(path)) if (!res.ok) { - throw new Error(res.statusText) + return null } - return res.text() + const contentType = res.headers.get('content-type') ?? '' + const text = await res.text() + + const looksHtml = + contentType.includes('text/html') || + /^\s* Date: Fri, 28 Nov 2025 05:45:38 -0800 Subject: [PATCH 2/3] Handle HTML doc responses and skip blueprint fetch --- src/services/nodeHelpService.ts | 34 +++++++++++++++-------------- src/workbench/utils/nodeHelpUtil.ts | 3 --- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/services/nodeHelpService.ts b/src/services/nodeHelpService.ts index 9c15a09c5dd..3bbebfdda3f 100644 --- a/src/services/nodeHelpService.ts +++ b/src/services/nodeHelpService.ts @@ -23,6 +23,7 @@ class NodeHelpService { locale: string ): Promise { const customNodeName = extractCustomNodeName(node.python_module) + let lastError: string | undefined if (!customNodeName) { throw new Error('Invalid custom node module') } @@ -30,14 +31,16 @@ class NodeHelpService { // Try locale-specific path first const localePath = `/extensions/${customNodeName}/docs/${node.name}/${locale}.md` const localeDoc = await this.tryFetchMarkdown(localePath) - if (localeDoc) return localeDoc + if (localeDoc.text) return localeDoc.text + lastError = localeDoc.errorText // Fall back to non-locale path const fallbackPath = `/extensions/${customNodeName}/docs/${node.name}.md` const fallbackDoc = await this.tryFetchMarkdown(fallbackPath) - if (fallbackDoc) return fallbackDoc + if (fallbackDoc.text) return fallbackDoc.text + lastError = fallbackDoc.errorText ?? lastError - throw new Error('Help not found') + throw new Error(lastError ?? 'Help not found') } private async fetchCoreNodeHelp( @@ -46,35 +49,34 @@ class NodeHelpService { ): Promise { const mdUrl = `/docs/${node.name}/${locale}.md` const doc = await this.tryFetchMarkdown(mdUrl) - if (!doc) { - throw new Error('Help not found') + if (!doc.text) { + throw new Error(doc.errorText ?? 'Help not found') } - return doc + return doc.text } /** * Fetch a markdown file and return its text, guarding against HTML/SPA fallbacks. - * Returns null when not OK or when the content looks like HTML. + * Returns null when not OK or when the content type indicates HTML. */ - private async tryFetchMarkdown(path: string): Promise { + private async tryFetchMarkdown( + path: string + ): Promise<{ text: string | null; errorText?: string }> { const res = await fetch(api.fileURL(path)) if (!res.ok) { - return null + return { text: null, errorText: res.statusText } } - const contentType = res.headers.get('content-type') ?? '' + const contentType = res.headers?.get?.('content-type') ?? '' const text = await res.text() - const looksHtml = - contentType.includes('text/html') || - /^\s* Date: Fri, 28 Nov 2025 05:52:45 -0800 Subject: [PATCH 3/3] nit --- src/workbench/utils/nodeHelpUtil.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/workbench/utils/nodeHelpUtil.ts b/src/workbench/utils/nodeHelpUtil.ts index 2bcd8996145..2efec34a021 100644 --- a/src/workbench/utils/nodeHelpUtil.ts +++ b/src/workbench/utils/nodeHelpUtil.ts @@ -15,6 +15,9 @@ export function extractCustomNodeName( export function getNodeHelpBaseUrl(node: ComfyNodeDefImpl): string { const nodeSource = getNodeSource(node.python_module) + if (nodeSource.type === NodeSourceType.Blueprint) { + return '' + } if (nodeSource.type === NodeSourceType.CustomNodes) { const customNodeName = extractCustomNodeName(node.python_module) if (customNodeName) {