{"record":{"id":"97db08aee6c7144b","repo":"n8n-io/n8n","slug":"expected-supabase-credentials-host-to-be-a-string","errorCode":null,"errorMessage":"Expected Supabase credentials host to be a string","messagePattern":"Expected Supabase credentials host to be a string","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts","lineNumber":33,"sourceCode":"\t});\n\n\tconst indexes = await client.listIndexes();\n\n\tconst results = (indexes.indexes ?? []).map((index) => ({\n\t\tname: index.name,\n\t\tvalue: index.name,\n\t}));\n\n\treturn { results };\n}\n\nexport async function supabaseTableNameSearch(this: ILoadOptionsFunctions) {\n\tconst credentials = await this.getCredentials('supabaseApi');\n\n\tconst results = [];\n\n\tif (typeof credentials.host !== 'string') {\n\t\tthrow new UserError('Expected Supabase credentials host to be a string');\n\t}\n\n\tconst { paths } = (await this.helpers.requestWithAuthentication.call(this, 'supabaseApi', {\n\t\theaders: {\n\t\t\tPrefer: 'return=representation',\n\t\t},\n\t\tmethod: 'GET',\n\t\turi: `${credentials.host}/rest/v1/`,\n\t\tjson: true,\n\t})) as { paths: IDataObject };\n\n\tfor (const path of Object.keys(paths)) {\n\t\t//omit introspection path\n\t\tif (path === '/') continue;\n\n\t\tresults.push({\n\t\t\tname: path.replace('/', ''),\n\t\t\tvalue: path.replace('/', ''),","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts#L15-L51","documentation":"A UserError from supabaseTableNameSearch (an ILoadOptionsFunctions credential-loading helper). It loads supabaseApi credentials and requires credentials.host to be a string before building the PostgREST URL; if the host is not a string it refuses to proceed. UserError means the user's configuration caused it.","triggerScenarios":"The Supabase table-name dropdown/option loader runs, getCredentials('supabaseApi') returns an object whose host is not a string (undefined, number, null) — e.g. credential fields left blank or a malformed credential record.","commonSituations":"Supabase credential 'host' (Project URL) left empty; credential partially saved; credential data corrupted or migrated incorrectly; the credential type changed and host is now under a different field name.","solutions":["Open the Supabase credential in n8n and fill the host/Project URL field with the full PostgREST base (e.g. https://<project>.supabase.co).","Re-save the credential after entering both host and serviceRole key.","Confirm the credential record used by the node is the updated one (not a stale duplicate).","If loading via API/JSON, ensure host is a string before assigning."],"exampleFix":"// before: credentials.host = undefined (field blank)\n// after:  credentials.host = 'https://abcdefgh.supabase.co'","handlingStrategy":"type-guard","validationCode":"const credentials = await this.getCredentials('supabaseApi'); if (typeof credentials.host !== 'string' || !credentials.host) { throw new Error('Configure the Supabase credential host (Project URL) before loading tables.'); }","typeGuard":"function hasStringHost(c: unknown): c is { host: string } { return !!c && typeof (c as any).host === 'string' && (c as any).host.length > 0; }","tryCatchPattern":"if (!hasStringHost(credentials)) { promptForCredential('supabaseApi'); return []; }","preventionTips":["Mark host as required in the credential definition so it cannot be blank.","Run a credential test before exposing the table-name loader.","Validate the host is a string at every entry point that builds a URL from it."],"tags":["supabase","credentials","config","validation","type-guard"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}