{"record":{"id":"7abebd6a9431abfe","repo":"can1357/oh-my-pi","slug":"sqlite-updates-require-at-least-one-column-value","errorCode":null,"errorMessage":"SQLite updates require at least one column value","messagePattern":"SQLite updates require at least one column value","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/sqlite-reader.ts","lineNumber":811,"sourceCode":"\tconst placeholders = entries.map(() => \"?\").join(\", \");\n\tconst bindings = entries.map(([, value]) => value);\n\tconst statement = db.prepare<SqliteRow, SQLQueryBindings[]>(\n\t\t`INSERT INTO ${quoteSqliteIdentifier(table)} (${columns}) VALUES (${placeholders})`,\n\t);\n\tstatement.run(...bindings);\n}\n\nexport function updateRowByKey(\n\tdb: Database,\n\ttable: string,\n\tpk: { column: string; type?: string },\n\tkey: string,\n\tdata: Record<string, unknown>,\n): number {\n\tgetTableMasterRow(db, table);\n\tconst entries = validateWriteColumns(db, table, data);\n\tif (entries.length === 0) {\n\t\tthrow new ToolError(\"SQLite updates require at least one column value\");\n\t}\n\n\tconst assignments = entries.map(([column]) => `${quoteSqliteIdentifier(column)} = ?`).join(\", \");\n\tconst bindings = entries.map(([, value]) => value);\n\tbindings.push(coerceLookupValue(key, pk.type ?? \"\"));\n\tconst statement = db.prepare<SqliteRow, SQLQueryBindings[]>(\n\t\t`UPDATE ${quoteSqliteIdentifier(table)} SET ${assignments} WHERE ${quoteSqliteIdentifier(pk.column)} = ?`,\n\t);\n\treturn statement.run(...bindings).changes;\n}\n\nexport function updateRowByRowId(db: Database, table: string, key: string, data: Record<string, unknown>): number {\n\tgetTableMasterRow(db, table);\n\tconst entries = validateWriteColumns(db, table, data);\n\tif (entries.length === 0) {\n\t\tthrow new ToolError(\"SQLite updates require at least one column value\");\n\t}\n","sourceCodeStart":793,"sourceCodeEnd":829,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/sqlite-reader.ts#L793-L829","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Include at least one valid column name and value in the update payload","Check the table schema (db.sqlite:table) to confirm exact column names","If keys were filtered out due to type coercion, ensure values serialize as valid column values"],"exampleFix":"// before\nupdateRow(db, \"users\", \"42\", {})\n// after\nupdateRow(db, \"users\", \"42\", { name: \"Alice\" })","handlingStrategy":"validation","validationCode":"const tableCols = new Set(\n  db.query(`PRAGMA table_info(${quoteSqliteIdentifier(table)})`).all().map(c => c.name),\n);\nconst validEntries = Object.entries(data).filter(([k]) => tableCols.has(k));\nif (validEntries.length === 0) {\n  throw new Error(\"Update payload has no valid column names for this table\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  updateRowByPk(db, table, key, data);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"at least one column value\")) {\n    // inspect schema and rebuild payload with real column names\n  } else throw err;\n}","preventionTips":["Always send at least one real column=value pair on updates","Fetch the table schema first to confirm column names before building payloads","Guard against empty objects reaching the update call programmatically"],"tags":["sqlite","update","validation"],"backgroundTag":"empty-update-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}