{"record":{"id":"5206452d36ce4147","repo":"NationalSecurityAgency/ghidra","slug":"more-than-one-match","errorCode":null,"errorMessage":"More than one match","messagePattern":"More than one match","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStore.java","lineNumber":1188,"sourceCode":"\t}\n\n\t/**\n\t * Search a column index for a single object having the given value\n\t * \n\t * @param columnIndex the indexed column's number\n\t * @param field a field holding the value to seek\n\t * @return the object, if found, or null\n\t * @throws IOException if there's an issue reading the table\n\t * @throws IllegalStateException if the object is not unique\n\t */\n\tprotected T findOneObject(int columnIndex, Field field) throws IOException {\n\t\t// TODO: Support non-long keys, eventually.\n\t\tField[] found = table.findRecords(field, columnIndex);\n\t\tif (found.length == 0) {\n\t\t\treturn null;\n\t\t}\n\t\tif (found.length != 1) {\n\t\t\tthrow new IllegalStateException(\"More than one match\");\n\t\t}\n\t\treturn getObjectAt(found[0].getLongValue());\n\t}\n\n\t/**\n\t * Search a column index for all objects having the given value\n\t * \n\t * @param columnIndex the indexed column's number\n\t * @param field a field holding the value to seek\n\t * @return the collection of objects found, possibly empty but never null\n\t * @throws IOException if there's an issue reading the table\n\t */\n\tprotected DBCachedObjectStoreFoundKeysValueCollection<T> findObjects(int columnIndex,\n\t\t\tField field) throws IOException {\n\t\tField[] found = table.findRecords(field, columnIndex);\n\t\treturn new DBCachedObjectStoreFoundKeysValueCollection<>(this, adapter, lock, found);\n\t}\n","sourceCodeStart":1170,"sourceCodeEnd":1206,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStore.java#L1170-L1206","documentation":"Thrown (unchecked IllegalStateException) by findOneObject when table.findRecords returns more than one record for the given field value. findOneObject assumes the value is unique; multiple matches indicate a uniqueness violation (duplicates) or misuse of a find-one lookup on a non-unique column.","triggerScenarios":"Querying a column that contains duplicate values via a method that assumes uniqueness; a unique index/constraint was not enforced so duplicate rows accumulated; data corruption or a write path that bypassed uniqueness checks.","commonSituations":"A 'unique key' column that lost its uniqueness guarantee; concurrent inserts creating duplicates; migrating legacy data with dupes into a store; using findOneObject on a column that was never intended to be unique.","solutions":["If the column may legitimately have duplicates, use the multi-result find (findObjects) instead of findOneObject.","Enforce uniqueness: declare a unique index / dedupe existing data so findOneObject's precondition holds.","Audit the write path that populated duplicates and fix the upstream insertion logic.","Run a cleanup pass to remove/merge duplicate rows before re-querying."],"exampleFix":"// before\nT obj = store.findOneObject(nameCol, field); // IllegalStateException on dupes\n\n// after: query for all matches when uniqueness isn't guaranteed\nCollection<T> matches = store.findObjects(nameCol, field);\nif (matches.size() > 1) {\n    throw new IllegalStateException(\"expected unique, got \" + matches.size());\n}\nT obj = matches.isEmpty() ? null : matches.iterator().next();","handlingStrategy":"validation","validationCode":"// For columns that may have duplicates, query all matches\nCollection<T> matches = store.findObjects(columnIndex, field);\nif (matches.size() != 1) {\n    // not unique: dedupe, enforce a unique index, or handle multiple\n}","typeGuard":null,"tryCatchPattern":"try {\n    T obj = store.findOneObject(columnIndex, field);\n} catch (IllegalStateException e) {\n    if (\"More than one match\".equals(e.getMessage())) { /* use findObjects; dedupe */ }\n    else throw e;\n}","preventionTips":["Use findObjects for columns that may have duplicate values.","Enforce a unique index when findOneObject's uniqueness precondition is required.","Audit insert paths that bypass uniqueness checks."],"tags":["database","uniqueness","duplicate-data","illegal-state","data-integrity","unchecked-exception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}