{"record":{"id":"9acd5b78bd69dbb8","repo":"FlowiseAI/Flowise","slug":"failed-to-parse-supabase-filter-error-message","errorCode":null,"errorMessage":"Failed to parse Supabase filter: ${error.message}","messagePattern":"Failed to parse Supabase filter: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/vectorstores/Supabase/filterParser.ts","lineNumber":48,"sourceCode":"\n    /**\n     * Safely parse a Supabase RPC filter string into a function\n     * @param filterString The filter string (e.g., 'filter(\"metadata->a::int\", \"gt\", 5).filter(\"metadata->c::int\", \"gt\", 7)')\n     * @returns A function that can be applied to an RPC object\n     * @throws Error if the filter string contains unsafe patterns\n     */\n    static parseFilterString(filterString: string): (rpc: any) => any {\n        try {\n            // Clean and validate the filter string\n            const cleanedFilter = this.cleanFilterString(filterString)\n\n            // Parse the filter chain\n            const filterChain = this.parseFilterChain(cleanedFilter)\n\n            // Build the safe filter function\n            return this.buildFilterFunction(filterChain)\n        } catch (error) {\n            throw new Error(`Failed to parse Supabase filter: ${error.message}`)\n        }\n    }\n\n    private static cleanFilterString(filter: string): string {\n        // Remove comments and normalize whitespace\n        filter = filter.replace(/\\/\\/.*$/gm, '').replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n        filter = filter.replace(/\\s+/g, ' ').trim()\n\n        // Remove trailing semicolon if present\n        if (filter.endsWith(';')) {\n            filter = filter.slice(0, -1).trim()\n        }\n\n        return filter\n    }\n\n    private static parseFilterChain(filter: string): Array<{ method: string; args: any[] }> {\n        const chain: Array<{ method: string; args: any[] }> = []","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/vectorstores/Supabase/filterParser.ts#L30-L66","documentation":"`FilterParser.parseFilterString` is the top-level entry that cleans the filter string, parses the method chain, and builds a safe function. Any error thrown by those inner steps is caught here and re-thrown prefixed with 'Failed to parse Supabase filter:'. It is an umbrella message — the real reason (disallowed method/operator, dangerous argument, empty chain) is in `error.message` appended to the prefix.","triggerScenarios":"Passing any malformed or unsupported filter string: unknown method, unknown operator, empty string, dangerous token (require/process/eval/Function), unparseable arguments, or a method not callable on the RPC at build time.","commonSituations":"User-authored filter from a chatflow textarea with a typo; filter built for a different Supabase version; copy-paste of raw PostgREST syntax the mini-DSL does not support.","solutions":["Read the appended inner message to find the specific sub-error (method/operator/argument).","Restrict the filter string to the documented DSL: only `filter|order|limit|range|single|maybeSingle` with allowed operators.","Validate the filter string client-side before sending it to parseFilterString.","Strip comments and trailing semicolons (the parser does this, but avoid relying on it)."],"exampleFix":"// before\nFilterParser.parseFilterString(userInput)  // throws generic 'Failed to parse Supabase filter: ...'\n\n// after (surface inner cause)\ntry { FilterParser.parseFilterString(userInput) }\ncatch (e) { throw new Error(`Filter '${userInput}' rejected: ${e.message}`) }","handlingStrategy":"validation","validationCode":"function tryParseFilter(s: string) {\n  try { return FilterParser.parseFilterString(s) }\n  catch (e) { throw new Error(`Filter rejected ('${s}'): ${(e as Error).message}`) }\n}","typeGuard":"function isFilterString(v: unknown): v is string { return typeof v === 'string' && v.trim().length > 0 }","tryCatchPattern":"try { fn = FilterParser.parseFilterString(raw) } catch (e) { /* read appended inner cause */ throw new Error(`Bad filter: ${(e as Error).message}`) }","preventionTips":["Validate the filter string against the documented DSL before parsing.","Always read the appended inner message for the real sub-error.","Reject empty strings upstream instead of relying on the parser.","Treat the parser as a security boundary; do not feed raw user SQL."],"tags":["supabase","filter-parser","input-validation","security","typescript"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}