n8n-io/n8n · error · NodeOperationError
SQL operation "${blockedKeyword}" is not allowed
Error message
SQL operation "${blockedKeyword}" is not allowed What it means
Safety guard thrown by the SQL Agent when the LLM-generated SQL contains a destructive or mutating keyword. The detectBlockedSqlKeyword function strips comments and string literals, then matches any of INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER, CREATE, REPLACE, MERGE as whole words. The agent is intentionally read-only.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/execute.ts:165
appDataSource: dataSource,
includesTables: includedTablesArray.length > 0 ? includedTablesArray : undefined,
ignoreTables: ignoredTablesArray.length > 0 ? ignoredTablesArray : undefined,
sampleRowsInTableInfo: includedSampleRows ?? 3,
});
const toolkit = new SqlToolkit(dbInstance, model);
const agentExecutor = createSqlAgent(model, toolkit, agentOptions);
agentExecutor.tools = agentExecutor.tools.map((tool) => {
if (tool.name !== 'query-sql') return tool;
return new DynamicTool({
name: tool.name,
description: tool.description,
func: async (sqlInput: string) => {
const blockedKeyword = detectBlockedSqlKeyword(sqlInput);
if (blockedKeyword) {
throw new NodeOperationError(
this.getNode(),
`SQL operation "${blockedKeyword}" is not allowed`,
{ itemIndex: i },
);
}
return String(await tool.invoke(sqlInput));
},
});
});
const memory = (await this.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as
| BaseChatMemory
| undefined;
agentExecutor.memory = memory;
let chatHistory = '';
if (memory) {View on GitHub (pinned to 5ac6606e81)
Solutions
- Reframe the prompt to make clear only read-only SELECT queries are allowed.
- Connect a read-only database user so even if the guard were bypassed the DB rejects writes.
- If writes are genuinely required, use a dedicated SQL node (Postgres/MySQL) instead of the SQL Agent.
Defensive patterns
Strategy: validation
Validate before calling
// Defensive check at the workflow authoring layer: warn users the agent is read-only.
// detectBlockedSqlKeyword is the runtime guard — pair it with a read-only DB user.
const dbUser = credentialData.username;
if (!dbUser || dbUser.endsWith('_readonly') === false) {
console.warn('SQL Agent should connect with a read-only database user.');
} Type guard
function isReadOnlySql(sql: string): boolean {
return detectBlockedSqlKeyword(sql) === undefined;
} Try / catch
try {
return String(await tool.invoke(sqlInput));
} catch (e) {
if (e instanceof NodeOperationError && /SQL operation/.test(e.message)) {
// Return a structured error so the agent can recover and try a SELECT instead
return JSON.stringify({ error: 'blocked-sql-operation', sql: sqlInput });
}
throw e;
} Prevention
- Connect the SQL Agent with a read-only database credential so writes are impossible at the DB level.
- Phrase prompts to request analysis, not modification.
- Document to end-users that the agent is read-only.
When it happens
Trigger: The model emits a tool call to 'query-sql' whose SQL argument contains any blocked keyword outside of a string literal or comment. e.g. the LLM tries DROP TABLE users or UPDATE accounts SET ....
Common situations: User asks the agent to 'clean up' or 'modify' records; the LLM hallucinates a schema fix involving DDL; prompt encourages write operations; few-shot examples leak mutating SQL.
Related errors
- The ‘prompt’ parameter is empty.
- No binary data found, please connect a binary to the input i
- No data source found, please configure data source
- No binary data received.
- Could not connect to database
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/9cb59dee7d9c5332.
Report an issue: GitHub.