knex/knex · error · Error
Parsing CREATE INDEX failed at [${result.input.slice(result.
Error message
Parsing CREATE INDEX failed at [${result.input.slice(result.index).map((t) => t.text).join(' ')}] of "${sql}" What it means
Same parser infrastructure as CREATE TABLE, but for CREATE INDEX statements. When rebuilding a table knex must re-create its indexes, so it parses each existing CREATE INDEX. If the index DDL uses syntax the parser rejects (partial-index WHERE clauses with unsupported operators, expression indexes with complex expressions, collations, etc.), parsing fails with the unparsed remainder and original SQL.
Source
Thrown at lib/dialects/sqlite3/schema/internal/parser.js:35
const result = createTable({ input: tokenize(sql, TOKENS) });
if (!result.success) {
throw new Error(
`Parsing CREATE TABLE failed at [${result.input
.slice(result.index)
.map((t) => t.text)
.join(' ')}] of "${sql}"`
);
}
return result.ast;
}
function parseCreateIndex(sql) {
const result = createIndex({ input: tokenize(sql, TOKENS) });
if (!result.success) {
throw new Error(
`Parsing CREATE INDEX failed at [${result.input
.slice(result.index)
.map((t) => t.text)
.join(' ')}] of "${sql}"`
);
}
return result.ast;
}
function createTable(ctx) {
return s(
[
t({ text: 'CREATE' }, (v) => null),
temporary,
t({ text: 'TABLE' }, (v) => null),
exists,
schema,View on GitHub (pinned to e25d54bcb7)
Solutions
- Drop and recreate the problematic index using a parser-compatible CREATE INDEX before running the alter.
- Perform the table alter manually with raw SQL so knex's index parser is bypassed.
- Simplify the index definition (plain column indexes, simple WHERE clauses) and upgrade knex for broader coverage.
Example fix
// before
await knex.schema.alterTable('t', (b) => b.setNullable('c'));
// index was: CREATE INDEX i ON t (lower(name)) WHERE active = 1;
// after
await knex.raw('DROP INDEX i');
await knex.schema.alterTable('t', (b) => b.setNullable('c'));
await knex.raw('CREATE INDEX i ON t (lower(name)) WHERE active = 1'); Defensive patterns
Strategy: try-catch
Validate before calling
const { parseCreateIndex } = require('knex/lib/dialects/sqlite3/schema/internal/parser');
async function assertIndexesParsable(knex, table) {
const rows = await knex.raw(`select sql from sqlite_master where type='index' and tbl_name=?`, [table]);
for (const r of rows) {
if (!r.sql) continue;
try { parseCreateIndex(r.sql); } catch (e) { throw new Error(`Index DDL not parser-compatible: ${r.sql}`); }
}
} Try / catch
try {
await knex.schema.alterTable('t', (b) => b.setNullable('c'));
} catch (e) {
if (/Parsing CREATE INDEX failed/i.test(e.message)) {
// drop/recreate the offending index manually, or perform raw alter
} else throw e;
} Prevention
- Prefer simple index definitions that knex's parser supports.
- Pre-flight parse index DDL before alter migrations.
- Recreate complex indexes after the alter via raw SQL.
When it happens
Trigger: Any table-rebuild DDL op (dropColumn, setNullable, dropForeign, etc.) on a table that has an index whose CREATE INDEX statement exceeds the parser's coverage. The error surfaces during the index-recreate phase of the rebuild.
Common situations: Indexes created via raw SQL with features beyond knex's parser. Expression indexes with functions or operators the parser grammar doesn't handle. Partial indexes with complex predicates.
Related errors
- Parsing CREATE TABLE failed at [${result.input.slice(result.
- No matching tokenizer rule found at: [${text.substring(index
- Refusing to create an unsafe transaction: client.strictForei
- Refusing to create transaction: unable to change `foreign_ke
- Unable to drop last column from table
AI-assisted analysis of knex/knex@e25d54bcb7 (2026-08-03).
Data as JSON: /data/errors/035310c434cb5071.json.
Report an issue: GitHub.