{"record":{"id":"090970a0c2641cb2","repo":"Zie619/n8n-workflows","slug":"please-add-your-api-key-for-searchapi-io-to-this-n","errorCode":null,"errorMessage":"Please add your API key for searchapi.io to this node","messagePattern":"Please add your API key for searchapi\\.io to this node","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"workflows/Manual/0399_Manual_Stickynote_Automate_Triggered.json","lineNumber":70,"sourceCode":"        \"color\": 7,\n        \"height\": 220.82906011310624,\n        \"content\": \"## About\\nThis workflow shows how you can write LangChain code in n8n (and import its modules if required).\\n\\nThe workflow fetches a video from YouTube and produces a textual summary of it.\"\n      },\n      \"typeVersion\": 1,\n      \"notes\": \"This stickyNote node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"a43bb1c5-dd90-4331-930c-128ef0ecb38a\",\n      \"name\": \"LangChain Code\",\n      \"type\": \"n8n-nodes-base.noOp\",\n      \"position\": [\n        -380,\n        20\n      ],\n      \"parameters\": {\n        \"code\": {\n          \"execute\": {\n            \"code\": \"// IMPORTANT: add in your API key for searchapi.io below\\nconst searchApiKey = \\\"<YOUR API KEY>\\\"\\n\\nconst { loadSummarizationChain } = require(\\\"langchain/chains\\\");\\nconst { SearchApiLoader } = require(\\\"@n8n/n8n-nodes-langchain/node_modules/@langchain/community/document_loaders/web/searchapi.cjs\\\");\\nconst { PromptTemplate } = require(\\\"@langchain/core/prompts\\\");\\nconst { TokenTextSplitter } = require(\\\"langchain/text_splitter\\\");\\nconst loader = new SearchApiLoader({\\n  engine: \\\"youtube_transcripts\\\",\\n  video_id: $input.item.json.videoId,\\n  apiKey: searchApiKey,\\n});\\n\\nif (searchApiKey == \\\"<YOUR API KEY>\\\") {\\n  throw new Error(\\\"Please add your API key for searchapi.io to this node\\\")\\n}\\n\\nconst docs = await loader.load();\\n\\nconst splitter = new TokenTextSplitter({\\n  chunkSize: 10000,\\n  chunkOverlap: 250,\\n});\\n\\nconst docsSummary = await splitter.splitDocuments(docs);\\n\\nconst llmSummary = await this.getInputConnectionData('ai_languageModel', 0);\\n\\nconst summaryTemplate = `\\nYou are an expert in summarizing YouTube videos.\\nYour goal is to create a summary of a podcast.\\nBelow you find the transcript of a podcast:\\n--------\\n{text}\\n--------\\n\\nThe transcript of the podcast will also be used as the basis for a question and answer bot.\\nProvide some examples questions and answers that could be asked about the podcast. Make these questions very specific.\\n\\nTotal output will be a summary of the video and a list of example questions the user could ask of the video.\\n\\nSUMMARY AND QUESTIONS:\\n`;\\n\\nconst SUMMARY_PROMPT = PromptTemplate.fromTemplate(summaryTemplate);\\n\\nconst summaryRefineTemplate = `\\nYou are an expert in summarizing YouTube videos.\\nYour goal is to create a summary of a podcast.\\nWe have provided an existing summary up to a certain point: {existing_answer}\\n\\nBelow you find the transcript of a podcast:\\n--------\\n{text}\\n--------\\n\\nGiven the new context, refine the summary and example questions.\\nThe transcript of the podcast will also be used as the basis for a question and answer bot.\\nProvide some examples questions and answers that could be asked about the podcast. Make\\nthese questions very specific.\\nIf the context isn't useful, return the original summary and questions.\\nTotal output will be a summary of the video and a list of example questions the user could ask of the video.\\n\\nSUMMARY AND QUESTIONS:\\n`;\\n\\nconst SUMMARY_REFINE_PROMPT = PromptTemplate.fromTemplate(\\n  summaryRefineTemplate\\n);\\n\\nconst summarizeChain = loadSummarizationChain(llmSummary, {\\n  type: \\\"refine\\\",\\n  verbose: true,\\n  questionPrompt: SUMMARY_PROMPT,\\n  refinePrompt: SUMMARY_REFINE_PROMPT,\\n});\\n\\nconst summary = await summarizeChain.run(docsSummary);\\n\\nreturn [{json: { summary } } ];\"\n          }\n        },\n        \"inputs\": {\n          \"input\": [\n            {\n              \"type\": \"main\",\n              \"required\": true,\n              \"maxConnections\": 1\n            },\n            {\n              \"type\": \"ai_languageModel\",\n              \"required\": true,\n              \"maxConnections\": 1\n            }\n          ]\n        },\n        \"outputs\": {\n          \"output\": [","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/Zie619/n8n-workflows/blob/94007c1445d9258a7da116646b79473e7c7c3282/workflows/Manual/0399_Manual_Stickynote_Automate_Triggered.json#L52-L88","documentation":"Deliberate guard inside the 'LangChain Code' noOp node (workflow 0399): the template hardcodes searchApiKey = '<YOUR API KEY>' and throws this exact message when the value is still the placeholder. The check runs after the SearchApiLoader is constructed but before loader.load(), so it is an intentional fail-fast for an unconfigured template.","triggerScenarios":"Executing the YouTube-transcript summarization workflow without editing the embedded code node and replacing the placeholder string. Any execution, manual or triggered, hits the throw because searchApiKey is a compile-time constant in the node.","commonSituations":"Imported n8n template with an in-code API key placeholder rather than a credential; user clicks Execute before reading the sticky-note instructions; key pasted into the wrong spot (e.g. the loader call) leaving the constant unchanged.","solutions":["Open the 'LangChain Code' node parameters and replace \"<YOUR API KEY>\" with a real searchapi.io key.","Better: move the key out of the code — read it from an n8n credential or $env (see exampleFix) so the workflow JSON carries no secret.","Rotate the key on searchapi.io if it was ever committed inside the JSON.","Verify with a single manual execution on one videoId before scheduling."],"exampleFix":"// before\nconst searchApiKey = \"<YOUR API KEY>\";\n// ...\nif (searchApiKey == \"<YOUR API KEY>\") {\n  throw new Error(\"Please add your API key for searchapi.io to this node\")\n}\n\n// after\nconst searchApiKey = $env.SEARCHAPI_IO_API_KEY; // set via n8n environment variable\nif (!searchApiKey) {\n  throw new Error(\"SEARCHAPI_IO_API_KEY is not configured in the n8n environment\");\n}","handlingStrategy":"validation","validationCode":"const searchApiKey = $env.SEARCHAPI_IO_API_KEY;\nif (!searchApiKey || searchApiKey.length < 10) {\n  throw new Error('SEARCHAPI_IO_API_KEY is not configured in the n8n environment');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store third-party keys in n8n credentials or environment variables, never as literals inside Code nodes.","Treat any '<YOUR ...>' placeholder in imported templates as a blocking setup step before first execution.","Never commit workflow JSONs containing real keys; rotate any key that was."],"tags":["n8n","api-key","configuration","template","secrets"],"backgroundTag":null,"analyzedSha":"94007c1445d9258a7da116646b79473e7c7c3282","analyzedAt":"2026-08-15T04:10:37.591Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}