Describe the bug
Any chatflow using OpenAI Embedding → (In-Memory / vector) store → Retrieval QA Chain fails at prediction with HTTP 500:
predictionsServices.buildChatflow - Cannot read private member from an object whose class did not declare it
TypeError: Cannot read private member from an object whose class did not declare it
at Object.__classPrivateFieldGet (.../openai/internal/tslib.js)
at OpenAI.buildURL (.../openai/client.js)
at OpenAI.buildRequest / makeRequest
at .../@langchain/openai/dist/embeddings.cjs (client.embeddings.create)
Chat-model flows are not affected.
Root cause
resolveVariables() in packages/server/src/utils/index.ts runs cloneDeep(reactFlowNodeData). For the ending node, reactFlowNodeData carries the node's already-built live .instance — a chain that transitively holds an OpenAIEmbeddings whose cached openai SDK client (this.client) was primed while indexing documents.
cloneDeep reconstructs that client with the correct prototype but never runs its constructor, so the clone is missing from openai v6's private-member brand WeakSet (_OpenAI_instances). The next request fails the brand check inside OpenAI.buildURL. ChatOpenAI is unaffected because it doesn't cache a client into the cloned data (it lazily builds a fresh, branded client per call).
This is the same class as #535 (deep-cloning live components — gRPC) and #614 (same error, Redis client). A FAISS-only omit-and-merge workaround once lived in resolveVariables; it has since been removed, so the general problem is back and now hits the very common OpenAI-embeddings RAG path with openai@6's stricter ES private-member enforcement.
Minimal repro (no Flowise server needed)
const { OpenAIEmbeddings } = require('@langchain/openai') // openai v6 underneath
const { cloneDeep } = require('lodash')
const e = new OpenAIEmbeddings({ openAIApiKey: process.env.OPENAI_API_KEY })
await e.embedQuery('warm up') // primes & caches e.client (branded)
await cloneDeep(e).embedQuery('x') // throws: Cannot read private member ... at OpenAI.buildURL
In-product: build Plain Text → Recursive Splitter → OpenAI Embedding → In-Memory Vector Store → Retrieval QA Chain and call POST /api/v1/prediction/:id.
Setup / Environment
- Flowise
3.1.2 (root cause also present on main)
@langchain/openai 1.2.5, openai 6.19.0, Node 20+
Suggested fix
Don't deep-clone a node's live .instance in resolveVariables — omit it from the clone and merge the original back (generalizes the previously-removed FAISS workaround). PR incoming.
Describe the bug
Any chatflow using OpenAI Embedding → (In-Memory / vector) store → Retrieval QA Chain fails at prediction with HTTP 500:
Chat-model flows are not affected.
Root cause
resolveVariables()inpackages/server/src/utils/index.tsrunscloneDeep(reactFlowNodeData). For the ending node,reactFlowNodeDatacarries the node's already-built live.instance— a chain that transitively holds anOpenAIEmbeddingswhose cachedopenaiSDK client (this.client) was primed while indexing documents.cloneDeepreconstructs that client with the correct prototype but never runs its constructor, so the clone is missing fromopenaiv6's private-member brandWeakSet(_OpenAI_instances). The next request fails the brand check insideOpenAI.buildURL.ChatOpenAIis unaffected because it doesn't cache a client into the cloned data (it lazily builds a fresh, branded client per call).This is the same class as #535 (deep-cloning live components — gRPC) and #614 (same error, Redis client). A FAISS-only omit-and-merge workaround once lived in
resolveVariables; it has since been removed, so the general problem is back and now hits the very common OpenAI-embeddings RAG path withopenai@6's stricter ES private-member enforcement.Minimal repro (no Flowise server needed)
In-product: build
Plain Text → Recursive Splitter → OpenAI Embedding → In-Memory Vector Store → Retrieval QA Chainand callPOST /api/v1/prediction/:id.Setup / Environment
3.1.2(root cause also present onmain)@langchain/openai1.2.5,openai6.19.0, Node 20+Suggested fix
Don't deep-clone a node's live
.instanceinresolveVariables— omit it from the clone and merge the original back (generalizes the previously-removed FAISS workaround). PR incoming.