{"record":{"id":"f779f60397da4915","repo":"FlowiseAI/Flowise","slug":"client-is-not-initialized","errorCode":null,"errorMessage":"Client is not initialized","messagePattern":"Client is not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/MCP/core.ts","lineNumber":190,"sourceCode":"        if (this._tools === null) {\n            this.client = await this.createClient()\n\n            this._tools = await this.client.request({ method: 'tools/list' }, ListToolsResultSchema)\n\n            this.tools = await this.get_tools()\n\n            // Close the initial client after initialization\n            await this.client.close()\n        }\n    }\n\n    async get_tools(): Promise<Tool[]> {\n        if (this._tools === null || this.client === null) {\n            throw new Error('Must initialize the toolkit first')\n        }\n        const toolsPromises = this._tools.tools.map(async (tool: any) => {\n            if (this.client === null) {\n                throw new Error('Client is not initialized')\n            }\n            const argsSchema = tool.inputSchema ?? { type: 'object', properties: {} }\n            const safeName = sanitizeMCPToolName(tool.name)\n            const safeDescription = sanitizeMCPToolDescription(tool.description || tool.name)\n            return await MCPTool({\n                toolkit: this,\n                name: safeName,\n                description: safeDescription,\n                argsSchema\n            })\n        })\n        const res = await Promise.allSettled(toolsPromises)\n        const errors = res.filter((r) => r.status === 'rejected')\n        if (errors.length !== 0) {\n            console.error('MCP Tools failed to be resolved', errors)\n        }\n        const successes = res.filter((r) => r.status === 'fulfilled').map((r) => r.value)\n        return successes","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/MCP/core.ts#L172-L208","documentation":"Thrown inside the per-tool mapping loop in MCPToolkit.get_tools when this.client === null at the moment a tool wrapper is constructed. Because initialize() calls this.client.close() right after get_tools() returns, async scheduling can let the close (and any code that nulls the client) interleave with the still-running map callbacks, tripping the inner guard.","triggerScenarios":"get_tools() is running its Promise.allSettled over tools while this.client becomes null concurrently — e.g. initialize() proceeding to client.close() or external code nulling the client mid-loop. Each tool's MCPTool() closure captures this and re-checks this.client before building the tool.","commonSituations":"Concurrent initialize()/close() calls on the same toolkit; a second initialize() racing the first; tool construction deferred across an await while the original client is torn down.","solutions":["Do not call initialize() (or close()) on the same MCPToolkit concurrently; serialize lifecycle calls.","Avoid re-invoking get_tools() manually; use the cached toolkit.tools populated by initialize().","Use one MCPToolkit instance per session and never null its client externally."],"exampleFix":"// before\nawait toolkit.initialize()      // closes client after get_tools\nawait toolkit.get_tools()       // client now null -> throws\n\n// after\nawait toolkit.initialize()\nconst tools = toolkit.tools ?? [] // use cached result","handlingStrategy":"try-catch","validationCode":"// Ensure no concurrent close()/initialize() runs while get_tools() executes.\nif (toolkit.client === null) {\n  throw new Error('Refusing to call get_tools(): client was closed; create a new MCPToolkit')\n}","typeGuard":"const hasLiveClient = (tk: MCPToolkit): boolean => tk.client !== null","tryCatchPattern":"try {\n  return await toolkit.get_tools()\n} catch (e) {\n  if (e.message === 'Client is not initialized') {\n    // build a fresh toolkit and re-initialize instead of retrying on the closed one\n  }\n  throw e\n}","preventionTips":["Never call initialize()/close() on the same toolkit concurrently.","Snapshot this.tools immediately after initialize() and reuse the snapshot.","Avoid manual get_tools() calls; the cached array is already populated."],"tags":["mcp","concurrency","lifecycle"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}