{"record":{"id":"660b999c24ee63a9","repo":"n8n-io/n8n","slug":"parameter-key-must-be-a-string","errorCode":null,"errorMessage":"Parameter ${key} must be a string","messagePattern":"Parameter (.+?) must be a string","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.ts","lineNumber":150,"sourceCode":"): context is IExecuteFunctions | ISupplyDataFunctions {\n\t// IExecuteFunctions and ISupplyDataFunctions have addInputData method\n\t// ILoadOptionsFunctions does not\n\treturn 'addInputData' in context;\n}\n\nfunction getParameter(key: string, context: IFunctionsContext, itemIndex: number): string {\n\tlet value: unknown;\n\n\tif (isExecutionContext(context)) {\n\t\t// Execution context: includes itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, itemIndex, '', { extractValue: true });\n\t} else {\n\t\t// Load options context: no itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, '', { extractValue: true });\n\t}\n\n\tif (typeof value !== 'string') {\n\t\tthrow new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`);\n\t}\n\treturn value;\n}\n\nexport const getIndexName = getParameter.bind(null, INDEX_NAME);\n\nfunction getOptionValue<T>(\n\tname: string,\n\tcontext: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\tdefaultValue?: T,\n): T | undefined {\n\tconst options: IDataObject = context.getNodeParameter('options', itemIndex, {});\n\treturn options[name] !== undefined ? (options[name] as T) : defaultValue;\n}\n\ninterface ValidatedCredentials {\n\tendpoint: string;","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.ts#L132-L168","documentation":"getParameter() in VectorStoreAzureAISearch reads a node parameter with extractValue:true and requires the result to be a string. If the value is an object, array, number, or an expression resolving to a non-string, it throws NodeOperationError. getIndexName is getParameter bound to INDEX_NAME, so the index name is the most common offender.","triggerScenarios":"context.getNodeParameter(key, ..., { extractValue: true }) returns a non-string (e.g. an object/array from a fixed collection, or an expression whose result is not a string), failing the typeof value !== 'string' check.","commonSituations":"Using an expression for the index name that resolves to an object or array; a parameter value that n8n returns as a typed collection rather than a string; node-version mismatch changing a parameter's resolved type.","solutions":["Ensure the parameter (typically the index name) evaluates to a plain string — fix the expression so it returns a string.","If the value can legitimately be non-string, wrap it: pass a string literal or use a Set node to coerce it before the Azure AI Search node.","Open the node and re-enter the index name as a fixed string to verify."],"exampleFix":"// before: index name = {{ $json }} (an object)\n// after:  index name = {{ $json.indexName }} (a string field)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isStringParam(v: unknown): v is string {\n  return typeof v === 'string';\n}\n// usage: const v = context.getNodeParameter(key, itemIndex, '', { extractValue: true });\n// if (!isStringParam(v)) throw new Error(`${key} must resolve to a string`);","tryCatchPattern":null,"preventionTips":["When using expressions for string parameters, ensure they resolve to a string field, not an object.","Add a Set node upstream to coerce values to strings when sources are untyped."],"tags":["validation","typescript","azure-ai-search","vector-store","parameters"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}