can1357/oh-my-pi · error · ToolError
SQLite table '${table}' does not expose ROWID; use '?where='
Error message
SQLite table '${table}' does not expose ROWID; use '?where=' instead What it means
When a table has no declared primary key, row lookup falls back to the implicit rowid. Tables declared `WITHOUT ROWID` have no rowid at all, so single-value addressing is impossible and the tool throws, directing callers to `?where=`.
Source
Thrown at packages/coding-agent/src/tools/sqlite-reader.ts:715
}
const column = primaryKeyColumns[0]!;
return { column: column.name, type: column.type };
}
export function resolveTableRowLookup(db: Database, table: string): SqliteRowLookup {
const primaryKeyColumns = getPrimaryKeyColumns(db, table);
if (primaryKeyColumns.length === 1) {
const column = primaryKeyColumns[0]!;
return { kind: "pk", column: column.name, type: column.type };
}
if (primaryKeyColumns.length > 1) {
throw new ToolError(`SQLite table '${table}' has a composite primary key; use '?where=' instead`);
}
const schema = getTableSchema(db, table);
if (/\bWITHOUT\s+ROWID\b/i.test(schema)) {
throw new ToolError(`SQLite table '${table}' does not expose ROWID; use '?where=' instead`);
}
return { kind: "rowid" };
}
export function queryRows(
db: Database,
table: string,
opts: { limit: number; offset: number; order?: string; where?: string },
): { columns: string[]; rows: Record<string, unknown>[]; totalCount: number } {
const columns = getTableColumns(db, table);
const validatedWhere = validateWhereClause(opts.where);
const whereClause = validatedWhere ? ` WHERE ${validatedWhere}` : "";
const orderClause = resolveOrderClause(opts.order, columns);
const countSql = `SELECT COUNT(*) AS count FROM ${quoteSqliteIdentifier(table)}${whereClause}`;
const selectSql = `SELECT * FROM ${quoteSqliteIdentifier(table)}${whereClause}${orderClause} LIMIT ? OFFSET ?`;
const totalCount = db.prepare<SqliteCountRow, []>(countSql).get()?.count ?? 0;
const statement = db.prepare<SqliteRow, SQLQueryBindings[]>(selectSql);View on GitHub (pinned to 9690622007)
Solutions
- Look the row up by its actual column(s): `db.sqlite:kv?where=k='foo'`
- Use a raw query: `db.sqlite?q=SELECT * FROM kv WHERE k='foo'`
- Recreate the table as a normal rowid table with a single-column primary key if row addressing is required
Example fix
// before sqlite://app.db?settings:some_key // after sqlite://app.db?settings?where=key='some_key'
Defensive patterns
Strategy: validation
Validate before calling
const schemaRow = db.query("SELECT sql FROM sqlite_master WHERE name = ?").get(table);
if (schemaRow?.sql && /\bWITHOUT\s+ROWID\b/i.test(schemaRow.sql)) {
// no rowid: use ?where= or q= instead of table:key
} Try / catch
try {
const lookup = resolveTableRowLookup(db, table);
} catch (err) {
if (err instanceof ToolError && err.message.includes("does not expose ROWID")) {
// use where= selector on the table's real columns
} else throw err;
} Prevention
- Know your schema: WITHOUT ROWID tables are never rowid-addressable
- Use the real key columns in ?where= for WITHOUT ROWID tables
- Avoid declaring WITHOUT ROWID tables without a single-column PRIMARY KEY
When it happens
Trigger: Calling resolveTableRowLookup on a table created with `CREATE TABLE t (...) WITHOUT ROWID` that also lacks a single-column PRIMARY KEY (note: most WITHOUT ROWID tables DO have a PRIMARY KEY and would hit the composite branch instead; this fires for keyless WITHOUT ROWID tables).
Common situations: Key-value stores created as `CREATE TABLE kv(k TEXT PRIMARY KEY, v) WITHOUT ROWID` with a composite or unusual key setup; hand-rolled schemas copying the WITHOUT ROWID optimization without a usable single key.
Related errors
- SQLite table '${table}' has no column named '${column}'
- SQLite schema for table '${table}' is unavailable
- SQLite table '${table}' has a composite primary key; use '?w
- Failed to open auth database at '${dbPath}' after ${maxAttem
- Persistent credential block store ${store} is unavailable af
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3f9ccb43063b720e.
Report an issue: GitHub.