Skip to content

Fix: Prevent creating duplicate and empty entry type#15107

Merged
Siedlerchr merged 5 commits into
JabRef:mainfrom
pluto-han:fix-15074-and-15103
Feb 16, 2026
Merged

Fix: Prevent creating duplicate and empty entry type#15107
Siedlerchr merged 5 commits into
JabRef:mainfrom
pluto-han:fix-15074-and-15103

Conversation

@pluto-han

@pluto-han pluto-han commented Feb 13, 2026

Copy link
Copy Markdown
Collaborator

Related issues and pull requests

Closes #15074
Closes #15103

PR Description

This PR fixes the issue where entry types with duplicate or empty names can be created. These changes improve data integrity and provide a more reliable and predictable user experience when managing entry types. To address #15074, I add a duplicate check to find duplicate entry types. If check passes, a new entry type will be created, otherwise it will select existing entry type. To address #15103, I refactored the logic so that both the '+' button and the Enter key trigger the same method and then run validity check.

Required Verification Screenshot:
image

Test Video:
https://github.com/user-attachments/assets/10f1b0d3-5765-46b1-8f21-76a1be1b98a4

Steps to test

  1. Follow https://docs.jabref.org/setup/customentrytypes, open File -> Preferences -> Entry types

  2. Type some spaces or a string with spaces (e.g. "te st") or leave entry type empty

  3. Click '+' button or press enter key

  4. Expected result: No entry types are created, JabRef warns users 'Entry type cannot be empty and must not contain spaces.'

  5. Type 'book'

  6. Expected result: Select and scroll to existing entry type 'Book'

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@github-actions

Copy link
Copy Markdown
Contributor

Hey @pluto-han! 👋

Thank you for contributing to JabRef!

We have automated checks in place, based on which you will soon get feedback if any of them are failing. We also use Qodo for review assistance. It will update your pull request description with a review help and offer suggestions to improve the pull request.

After all automated checks pass, a maintainer will also review your contribution. Once that happens, you can go through their comments in the "Files changed" tab and act on them, or reply to the conversation if you have further inputs. You can read about the whole pull request process in our contribution guide.

Please ensure that your pull request is in line with our AI Usage Policy and make necessary disclosures.

@github-actions github-actions Bot added first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. status: no-bot-comments labels Feb 13, 2026
@testlens-app

testlens-app Bot commented Feb 13, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 60d5e9a
▶️ Tests: 11192 executed
⚪️ Checks: 72/72 completed


Learn more about TestLens at testlens.app.

@pluto-han pluto-han changed the title Fix 15074 and 15103 Fix: Prevent creating duplicate and empty entry type Feb 13, 2026
@pluto-han pluto-han marked this pull request as ready for review February 13, 2026 23:46
@github-actions

Copy link
Copy Markdown
Contributor

Do not mark a PR as ready-for-review while the CI is running. CI checks need to be completed and passed.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Prevent duplicate and empty entry type creation with validation

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Prevent creating duplicate entry types by checking existing types
• Prevent creating empty or space-containing entry types with validation
• Unify entry type creation logic for '+' button and Enter key
• Select and scroll to existing entry type when duplicate name entered
Diagram
flowchart LR
  A["User input entry type name"] --> B{"Validation check"}
  B -->|Invalid| C["Show warning message"]
  B -->|Valid| D{"Check for duplicates"}
  D -->|Duplicate found| E["Select existing entry type"]
  D -->|No duplicate| F["Create new entry type"]
  E --> G["Scroll to entry type"]
  F --> G
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTab.java 🐞 Bug fix +14/-1

Add validation and duplicate detection to entry type creation

• Modified addNewEntryType button action to call unified addEntryType() method
• Enhanced addEntryType() method with validation check to prevent invalid entries
• Added duplicate detection logic that selects and scrolls to existing entry type
• Prevents creation of entry types with empty names or spaces

jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTab.java


2. CHANGELOG.md 📝 Documentation +2/-0

Document entry type creation bug fixes

• Added entry for issue #15103 fix regarding empty or space-containing entry types
• Added entry for issue #15074 fix regarding duplicate entry type creation

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Remediation recommended

1. Changelog grammar in bullets 📘 Rule violation ✓ Correctness
Description
The new changelog entries contain grammatical issues (missing articles/awkward phrasing), reducing
clarity and professionalism. This violates the requirement to keep changelog/user-facing text free
of obvious typos/grammar problems.
Code

CHANGELOG.md[R46-47]

+- We fixed an issue where empty entry type or entry type with spaces can be created. [#15103](https://github.com/JabRef/jabref/issues/15103)
+- We fixed an issue where duplicate entry type can be created and overwrite existing entry type. [#15074](https://github.com/JabRef/jabref/issues/15074)
Evidence
PR Compliance ID 39 requires changelog text to be free of obvious typographical/grammatical issues.
The added changelog bullets read awkwardly (e.g., missing articles like "an" and phrasing like "can
be created"), indicating a documentation text-quality problem.

CHANGELOG.md[46-47]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The two newly added `Fixed` entries in `CHANGELOG.md` have awkward grammar (e.g., missing articles like "an") which reduces readability and violates text-quality requirements.

## Issue Context
These are user-facing release notes and should be written in clear, correct English.

## Fix Focus Areas
- CHANGELOG.md[46-47]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Non-space whitespace allowed 🐞 Bug ✓ Correctness
Description
Entry type validation only rejects the literal space character, so pasted tabs/NBSP/other whitespace
can still pass validation, evade the duplicate check, and be persisted as a new (unknown) entry
type. This can lead to “invisible” duplicates and malformed serialized custom entry type metadata.
Code

jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTab.java[R269-280]

+        if (!viewModel.entryTypeValidationStatus().isValid()) {
+            return;
+        }
+
+        String entryTypeName = viewModel.entryTypeToAddProperty().getValue();
+        for (EntryTypeViewModel existingEntryType : entryTypesTable.getItems()) {
+            if (existingEntryType.entryType().getValue().getType().getName().equalsIgnoreCase(entryTypeName)) {
+                this.entryTypesTable.getSelectionModel().select(existingEntryType);
+                this.entryTypesTable.scrollTo(existingEntryType);
+                return;
+            }
+        }
Evidence
The controller’s new flow gates creation on entryTypeValidationStatus() and then compares the raw
text field value against existing type names; however, the validator only checks for ASCII space ("
"), and type parsing/serialization preserves other whitespace. Therefore, a user can paste a
tab/NBSP-containing name that passes validation, doesn’t match any existing type by
equalsIgnoreCase, is stored as an UnknownEntryType (lowercased, whitespace preserved), and is
serialized/parses without trimming—creating hard-to-detect duplicates and potential metadata format
issues.

jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTab.java[267-280]
jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTabViewModel.java[74-77]
jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTabViewModel.java[139-145]
jablib/src/main/java/org/jabref/model/entry/types/UnknownEntryType.java[16-18]
jablib/src/main/java/org/jabref/model/entry/types/EntryTypeFactory.java[45-54]
jablib/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java[156-160]
jablib/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java[63-77]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Entry type creation now relies on `entryTypeValidationStatus()` and a string-based duplicate check. The current validator only rejects the literal ASCII space (`" "`), so pasted tabs/NBSP/other whitespace can still pass validation, evade the duplicate check, and create/persist malformed custom entry types.

### Issue Context
- `UnknownEntryType` preserves characters (only lowercases), `EntryTypeFactory.parse` does not trim, and custom entry type metadata serialization embeds the type name verbatim.
- This makes non-space whitespace variants hard to spot and can create “invisible” duplicates.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTabViewModel.java[74-77]
- jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTabViewModel.java[139-145]
- jabgui/src/main/java/org/jabref/gui/preferences/customentrytypes/CustomEntryTypesTab.java[267-280]

### Suggested approach
- Replace `!input.contains(" ")` with a predicate that rejects *any* whitespace character, e.g.:
 - `input != null && !input.isBlank() && input.chars().noneMatch(Character::isWhitespace)`
 - or regex `!input.matches(".*\\s+.*")`
- Normalize the input used for duplicate comparison and creation:
 - `String normalized = entryTypeName.strip();`
 - compare against `existingType.getName()` using consistent normalization (e.g., lowercase + strip).
- Update the validation message to say “whitespace” if behavior changes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@Siedlerchr Siedlerchr added the status: awaiting-second-review For non-trivial changes label Feb 16, 2026
@ThiloteE

Copy link
Copy Markdown
Member

Tried this PR.
Works very well for entrytypes. Good job!

I noticed the implementation for fields triggers a popup too, but doesn't completely prevent the emergence of a duplicate field. Pressing the "save" button will delete one of them, but which one? I know it wasn't part of the issue I posted, but if you can make it similar to how you handled the entrytypes, it would be nice, simply to keep coherency. Feel free to refrain from doing so, if you are completely out of time. 👍

grafik

@Siedlerchr Siedlerchr added this pull request to the merge queue Feb 16, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Feb 16, 2026
Merged via the queue into JabRef:main with commit 63c27bd Feb 16, 2026
72 checks passed
@pluto-han

pluto-han commented Feb 17, 2026

Copy link
Copy Markdown
Collaborator Author

but if you can make it similar to how you handled the entrytypes, it would be nice, simply to keep coherency. Feel free to refrain from doing so, if you are completely out of time.

I will work on it.

@ThiloteE

Copy link
Copy Markdown
Member

Note: Upgrading from 5.15 to this PR is without hassle.

How I tested:

  1. Open JabRef 5.15
  2. Open File>Preferences>Entry Types: Add custom entry type movie with fields test and editor set as required.
  3. Add an entry with those properties.
  4. Save and close JabRef
  5. Open a version of JabRef with this change (JabRef 6.0alpha5)
  6. Open File>Preferences>Entry Types: See that the custom entry type movie still holds my custom fields instead of the fields after reset to default.
  7. Open the entry in the entry editor and see that required fields tab still holds the fields test and editor.

Everything correct 👍

We are backwards compatible too, as users on old versions can import the new non-standard entry type configs as "custom entry type", which then again is perfectly fine to upgrade from.

RakockiW pushed a commit to RakockiW/jabref that referenced this pull request Mar 1, 2026
* Fix saving duplicate and empty entry type

* Fix saving duplicate and empty entry type

* update CHANGELOG.md

* Fix saving duplicate and empty entry type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. status: awaiting-second-review For non-trivial changes status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Saving custom entry type with blank name Saving custom entry type with same name overwrites existing entry type

3 participants