{"record":{"id":"8f986b7b535ef106","repo":"FlowiseAI/Flowise","slug":"invalid-sql-statement-multiple-statements-are-not","errorCode":null,"errorMessage":"Invalid SQL statement: multiple statements are not allowed","messagePattern":"Invalid SQL statement: multiple statements are not allowed","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/validator.ts","lineNumber":389,"sourceCode":" * All legitimate queries issued against sqlite by this chain (including langchain's own\n * schema introspection, which uses `pragma_table_info()` as a table-valued function\n * inside a SELECT) are single SELECT/WITH statements, so this restriction does not\n * affect normal operation.\n *\n * @param {string} sql The SQL statement to validate\n * @throws {Error} If the statement is not a single read-only SELECT/WITH statement\n */\nexport const assertReadOnlySqlStatement = (sql: string): void => {\n    if (!sql || typeof sql !== 'string') {\n        throw new Error('Invalid SQL statement: statement is required and must be a string')\n    }\n\n    let trimmed = sql.trim()\n    // Strip at most one trailing semicolon (+ trailing whitespace)\n    trimmed = trimmed.replace(/;\\s*$/, '')\n\n    if (trimmed.includes(';')) {\n        throw new Error('Invalid SQL statement: multiple statements are not allowed')\n    }\n\n    if (!/^(SELECT|WITH)\\b/i.test(trimmed)) {\n        throw new Error('Invalid SQL statement: only read-only SELECT/WITH statements are allowed')\n    }\n\n    if (/load_extension\\s*\\(/i.test(trimmed)) {\n        throw new Error('Invalid SQL statement: load_extension is not allowed')\n    }\n}\n\n/**\n * Sanitize a file name to prevent path traversal attacks.\n * Strips common storage prefixes, extracts the basename, runs it through\n * the `sanitize-filename` package, and rejects anything that still looks unsafe.\n *\n * @param {string} name The file name to sanitize\n */","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/validator.ts#L371-L407","documentation":"Thrown by assertReadOnlySqlStatement (packages/components/src/validator.ts:389) when, after stripping one optional trailing semicolon, the statement still contains ';'. This blocks stacked queries (e.g. 'SELECT 1; DROP TABLE x') which SQLite/TypeORM would otherwise execute in sequence.","triggerScenarios":"LLM-generated SQL contains multiple statements, e.g. 'SELECT * FROM t; SELECT * FROM u' or a trailing comment+semicolon like 'SELECT 1; -- done'. Any ';' beyond the single permitted trailing one trips it.","commonSituations":"LLMs trained on multi-statement scripts; copy-pasted schema-setup SQL; CTEs that incorrectly embed ';'.","solutions":["Send only one SELECT/WITH statement per call.","Strip trailing comments and the final ';' before submitting.","Tune the chain's prompt to forbid multi-statement output.","If you need multiple queries, run them as separate validated calls."],"exampleFix":"// before\nsql = 'SELECT * FROM users; SELECT * FROM orders;'\n\n// after\nsql = 'SELECT * FROM users'   // one statement, no trailing ';'","handlingStrategy":"validation","validationCode":"const one = String(sql ?? '').trim().replace(/;\\s*$/, '');\nif (one.includes(';')) throw new Error('multi-statement SQL rejected');\nassertReadOnlySqlStatement(one);","typeGuard":"const isSingleStatement = (s: unknown): s is string => typeof s === 'string' && !s.trim().replace(/;\\s*$/, '').includes(';');","tryCatchPattern":"try { assertReadOnlySqlStatement(sql) } catch (e) { if (e instanceof Error && /multiple statements/.test(e.message)) { sql = sql.split(';')[0] } else throw e }","preventionTips":["Send one SELECT/WITH per call.","Strip trailing comments and the final ';' before submission.","Prompt-tune the chain to forbid multi-statement output."],"tags":["sql","security","validation","sql-injection","sqlite","database","llm","flowise"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}