can1357/oh-my-pi · error · ToolError

SQLite updates require at least one column value

Error message

SQLite updates require at least one column value

What it means

updateRowByPk validates the supplied data against the table's real columns (validateWriteColumns) and requires at least one surviving column/value entry to build the SET clause. An empty data object (or one whose keys are all unknown to the table) would produce invalid SQL `SET ` — so the tool throws instead.

Source

Thrown at packages/coding-agent/src/tools/sqlite-reader.ts:811

	const placeholders = entries.map(() => "?").join(", ");
	const bindings = entries.map(([, value]) => value);
	const statement = db.prepare<SqliteRow, SQLQueryBindings[]>(
		`INSERT INTO ${quoteSqliteIdentifier(table)} (${columns}) VALUES (${placeholders})`,
	);
	statement.run(...bindings);
}

export function updateRowByKey(
	db: Database,
	table: string,
	pk: { column: string; type?: string },
	key: string,
	data: Record<string, unknown>,
): number {
	getTableMasterRow(db, table);
	const entries = validateWriteColumns(db, table, data);
	if (entries.length === 0) {
		throw new ToolError("SQLite updates require at least one column value");
	}

	const assignments = entries.map(([column]) => `${quoteSqliteIdentifier(column)} = ?`).join(", ");
	const bindings = entries.map(([, value]) => value);
	bindings.push(coerceLookupValue(key, pk.type ?? ""));
	const statement = db.prepare<SqliteRow, SQLQueryBindings[]>(
		`UPDATE ${quoteSqliteIdentifier(table)} SET ${assignments} WHERE ${quoteSqliteIdentifier(pk.column)} = ?`,
	);
	return statement.run(...bindings).changes;
}

export function updateRowByRowId(db: Database, table: string, key: string, data: Record<string, unknown>): number {
	getTableMasterRow(db, table);
	const entries = validateWriteColumns(db, table, data);
	if (entries.length === 0) {
		throw new ToolError("SQLite updates require at least one column value");
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Include at least one valid column name and value in the update payload
  2. Check the table schema (db.sqlite:table) to confirm exact column names
  3. If keys were filtered out due to type coercion, ensure values serialize as valid column values

Example fix

// before
updateRow(db, "users", "42", {})
// after
updateRow(db, "users", "42", { name: "Alice" })
Defensive patterns

Strategy: validation

Validate before calling

const tableCols = new Set(
  db.query(`PRAGMA table_info(${quoteSqliteIdentifier(table)})`).all().map(c => c.name),
);
const validEntries = Object.entries(data).filter(([k]) => tableCols.has(k));
if (validEntries.length === 0) {
  throw new Error("Update payload has no valid column names for this table");
}

Try / catch

try {
  updateRowByPk(db, table, key, data);
} catch (err) {
  if (err instanceof ToolError && err.message.includes("at least one column value")) {
    // inspect schema and rebuild payload with real column names
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the update path (`db.sqlite:table:key` with a write payload) where data is `{}`, or where every provided key fails column validation (misspelled or nonexistent column names).

Common situations: Sending an empty JSON body by mistake; a schema change renamed/removed columns so all payload keys are filtered out; building the payload programmatically from an empty object.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/7abebd6a9431abfe. Report an issue: GitHub.