NationalSecurityAgency/ghidra · critical · SQLException

Problem deleting executable record

Error message

Problem deleting executable record

What it means

Thrown by ExeTable.delete when super.delete(id) returns a row count greater than 1, meaning the delete affected multiple rows. Because exetable ids should be unique primary keys, deleting more than one row signals data corruption or a schema/constraint problem where the id is not unique. This is a data-integrity alarm.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/tables/ExeTable.java:140

	@Override
	public void create(Statement st) throws SQLException {
		st.executeUpdate(CREATE_STMT);
	}

	@Override
	public void drop(Statement st) throws SQLException {
		throw new UnsupportedOperationException("ExeTable may not be dropped");
	}

	@Override
	public int delete(long id) throws SQLException {
		int rowcount = super.delete(id);
		if (rowcount == 0) {
			throw new SQLException("Could not delete executable record");
		}
		if (rowcount > 1) {
			throw new SQLException("Problem deleting executable record");
		}
		return rowcount;
	}

	/**
	 * Pulls information out of the given {@link ExecutableRow} object into the given
	 * {@link ResultSet}
	 * 
	 * @param pgres the result set
	 * @param res the executable row
	 * @throws SQLException if there is a problem parsing the result set
	 */
	protected static void extractExecutableRow(ResultSet pgres, ExecutableRow res)
		throws SQLException {
		res.rowid = pgres.getInt(1);
		res.md5 = pgres.getString(2);
		res.exename = pgres.getString(3);
		res.arch_id = pgres.getInt(4);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Run a database integrity/reindex check on exetable and remove duplicate-id rows.
  2. Verify the exetable id column has a proper unique primary-key constraint enforced by the backend.
  3. If ids exceed Integer.MAX_VALUE, audit the BSim database for very large row ids (the setInt cast is a latent bug for huge databases).
  4. Restore from a known-good backup if corruption is severe.
Defensive patterns

Strategy: validation

Validate before calling

// Detect duplicate ids before deleting (data-integrity alarm).
// Run: SELECT id, COUNT(*) FROM exetable GROUP BY id HAVING COUNT(*) > 1
// If any results, the database is corrupted — do not proceed with delete.

Prevention

When it happens

Trigger: Calling delete(id) on an exetable where the id column is not uniquely constrained, so multiple rows share the id. Caused by a corrupted database, a failed/rolled-back migration that left duplicate rows, or a custom table layout that broke the primary-key assumption. The internal code casts id to int for the WHERE clause, so an int-overflow collision could also cause spurious multi-row matches if two distinct long ids truncate to the same int.

Common situations: Database corruption producing duplicate primary keys. A botched schema migration. Using a database backend that does not enforce primary-key uniqueness on exetable. Int-overflow if a long id exceeds Integer.MAX_VALUE and is truncated by setInt.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/f73ad38a20e6efcb. Report an issue: GitHub.