can1357/oh-my-pi · error · ToolError
${violation}
Error message
${violation} What it means
Thrown by validateWhereClause when the 'where' query parameter contains a disallowed construct, as detected by findWhereClauseViolation. The tool re-stricts WHERE clauses (forbidding keywords like LIMIT, and likely comments/multiple statements) so that user-supplied filters cannot alter pagination, escape the query, or execute arbitrary SQL.
Source
Thrown at packages/coding-agent/src/tools/sqlite-reader.ts:496
inDoubleQuote = true;
continue;
}
if (char === ";") return COMMENT_OR_TERMINATOR_ERROR;
if ((char === "-" && next === "-") || (char === "/" && next === "*") || (char === "*" && next === "/")) {
return COMMENT_OR_TERMINATOR_ERROR;
}
}
return keywordViolation;
}
function validateWhereClause(where: string | undefined): string | undefined {
if (!where) return undefined;
const trimmed = where.trim();
if (!trimmed) return undefined;
const violation = findWhereClauseViolation(trimmed);
if (violation) {
throw new ToolError(violation);
}
return trimmed;
}
function normalizeWriteValue(value: unknown, column: string): SqliteBinding {
if (value === null) return null;
if (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "boolean" ||
typeof value === "bigint"
) {
return value;
}
throw new ToolError(`SQLite column '${column}' only accepts JSON scalar values or null`);
}
function validateWriteColumns(View on GitHub (pinned to 9690622007)
Solutions
- Remove forbidden keywords (LIMIT, OFFSET, ORDER BY, etc.) from the where clause — use the tool's own limit/offset/order params instead
- Keep the where param a simple filter expression (column comparisons with AND/OR)
- Read the violation message — it names the exact offending construct
- If the filter can't be expressed without the forbidden clause, run a raw q=SELECT query instead
Example fix
// before ?where=active=1 LIMIT 10 // after ?where=active=1&limit=10
Defensive patterns
Strategy: validation
Validate before calling
const FORBIDDEN = /\b(limit|offset|order\s+by|union|;|--|\/\*)/i;
if (where && FORBIDDEN.test(where)) {
throw new Error(`where clause contains forbidden construct: ${where}`);
} Try / catch
try {
await reader.read(`db.sqlite/users?where=${encodeURIComponent(where)}`);
} catch (err) {
if (err instanceof ToolError && /forbidden|not allowed/i.test(err.message)) {
// sanitize the where clause or move pagination to dedicated params
} else throw err;
} Prevention
- Keep where clauses to simple boolean column expressions
- Use the tool's limit/offset/order params, never SQL clauses in where
- Validate user-supplied filters against a keyword blocklist before passing them
When it happens
Trigger: Passing where=age>18 LIMIT 5; where clauses with forbidden keywords (LIMIT/OFFSET etc.), semicolons, comments, or other dangerous patterns; stacking pagination manually inside where instead of using the tool's limit/offset params.
Common situations: Developers copying full SQL fragments including LIMIT into the where param; trying to sneak in ORDER BY inside where; prompt-generated SQL that includes trailing clauses.
Related errors
- SQLite order column '${column}' not found in table schema
- Unsupported SQLite selector
- SQLite limit must be a positive integer; got '${value}'
- SQLite offset must be a non-negative integer; got '${value}'
- ${label} must be an integer; got '${key}'
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/edd5fced9b41d325.
Report an issue: GitHub.