Skip to content

Bring changes from v7.11.4 to main#7683

Merged
grantfitzsimmons merged 41 commits intomainfrom
v7.11.4-prerelease
Feb 13, 2026
Merged

Bring changes from v7.11.4 to main#7683
grantfitzsimmons merged 41 commits intomainfrom
v7.11.4-prerelease

Conversation

@melton-jason
Copy link
Contributor

@melton-jason melton-jason commented Feb 4, 2026

Brings the changes from #7671 / v7.11.4 to main.

Checklist

  • Self-review the PR after opening it to make sure the changes look good and
    self-explanatory (or properly documented)
  • Add relevant issue to release milestone
  • Add pr to documentation list
  • Add automated tests

Testing instructions

Follow the testing instructions from Prevent broken transactions when autonumbering (#7671) (provided below) and ensure the functionality is correct with the updated branch:

Sample Database

To speed up setup for testing this Pull Request, i've set up a testing database that contains all resources required for testing:
Feel free to use the database!

User - spadmin
Password - testuser

Collections:

  • Fish
    • In the SCC Division
    • In the Ichthyology Discipline
    • Catalog Number of the format FSH-#########
    • One CollectionObject WorkBench Data Set
    • One Accession WorkBench Data Set
  • Plants
    • In the SCC Division
    • In the Botany Discipline
    • Catalog Number of the format #########
    • CO -> text2 of the format AAA-NNN-#########
      • Where A can be any letter and N can be any number
    • Locality -> text1 of the format #########
    • Two Collection Object WorkBench Data Sets
    • One Locality Data Set
  • Vascular Plants
  • In the SCC Division
  • In the Botany Discipline
  • CO -> text2 of the format AAA-NNN-#########
    • Where A can be any letter and N can be any number
  • Locality -> text1 of the format #########
  • One Collection Object WorkBench Data Set
  • Mammals
    • In the Test Division
    • In the Mammology Discipline
  • One Accession WorkBench Data Set

Where Accessions are scoped to Division:

issue-6490_scoped_accession_testing.sql.zip

Where Accessions are globally scoped:

issue-6490_global_accession_testing.sql.zip


General Concurrency with WorkBench

  • Start a WorkBench Upload or Validation operation on a sufficiently large Data Set (the operation needs to be in process while the below steps of General Concurrency are completed)
  • Open Specify in a new tab, window, or browser
  • Open a DataEntry form of the same table as the base table as the WorkBench Data Set, where one or fields have an autonumbering field format
  • Save the Data Entry record and ensure the record saves successfully
  • Reload the page and ensure Specify loads and still remains accessible

Concurrent Autonumbering with the WorkBench

  • Start a WorkBench Upload operation on a sufficiently large Data Set (the operation needs to be in process while some of the below steps of Concurrent Autonumbering with the WorkBench are completed) that contains two or more fields that will be autonumbered
  • Open Specify in a new tab, window, or browser
  • Open a DataEntry form of the same table as the base table as the WorkBench Data Set, where one or fields have an autonumbering field format
  • Save the Data Entry record and ensure the record saves successfully
  • Wait for the WorkBench Upload operation to complete
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.

Concurrent Autonumbering with Non Collection Scoping
Review Table Scoping Hiearchy for an overview on table scopes

With the Sample Database, this would be using the Locality Data Set in the Plants Collection with creating a new Locality in the Vascular Plants Collection

  • Start a WorkBench Upload operation on a sufficiently large Data Set (the operation needs to be in process while some of the below steps of Concurrent Autonumbering with Non Collection Scoping are completed) where the base table is not scoped to Collection that contains one or more fields that will be autonumbered
  • Open Specify in a new tab, window, or browser
  • Switch to a different Collection which is in the same scope as the records being uploaded
  • Open a DataEntry form of the same table as the base table as the WorkBench Data Set where one or more fields have an autonumbering field format
  • Save the Data Entry record and ensure the record saves successfully
  • Wait for the WorkBench Upload operation to complete
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.

Autonumbering with Variable Table Scoping

In a database with more than one Division where Accessions are scoped to Division

  • Start a WorkBench Upload operation on a sufficiently large Accession Data Set (the operation needs to be in process while some of the below steps of Concurrent Autonumbering with Non Collection Scoping are completed) where a field on Accession is being autonumbered
  • Open Specify in a new tab, window, or browser
  • Switch to a different Collection which is in a different Division as the records being uploaded
  • Open an Accession DataEntry form
  • Save the Accession and ensure the record saves successfully
  • Wait for the WorkBench Upload operation to complete
  • Ensure that the Accessions in different Divisions are independently auto-numbered (e.g., Accessions in different Divisions should not share the same autonumbering)

In a database with more than one Division where Accessions are globally scoped

  • Start a WorkBench Upload operation on a sufficiently large Accession Data Set (the operation needs to be in process while some of the below steps of Concurrent Autonumbering with Non Collection Scoping are completed) where a field on Accession is being autonumbered

  • Open Specify in a new tab, window, or browser

  • Switch to a different Collection which is in a different Division as the records being uploaded

  • Open an Accession DataEntry form

  • Save the Accession and ensure the record saves successfully

  • Wait for the WorkBench Upload operation to complete

  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results in the other Division

  • Generally ensure that autonumbering respects the scoping of Accessions (e.g, using DataEntry, create Accessions in different scopes and ensure they're autonumbered as expected)

General

  • Please also do general testing focused around autonumbering, especially with concurrent WorkBench uploads!

acwhite211 and others added 30 commits September 30, 2025 12:33
See #6490, #5337
Replaces #5404
Fixes #4148, #7560

This branch is largely the application of #7455 on `v7.11.3`
Based largely off the initial implementation at 5ed701a from #7399
@melton-jason melton-jason requested review from a team February 6, 2026 01:59
@melton-jason melton-jason marked this pull request as ready for review February 6, 2026 01:59
Copy link
Collaborator

@emenslin emenslin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Save the Data Entry record and ensure the record saves successfully
  • Reload the page and ensure Specify loads and still remains accessible
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Accession and ensure the record saves successfully
  • Ensure that the Accessions in different Divisions are independently auto-numbered (e.g., Accessions in different Divisions should not share the same autonumbering)
  • Save the Accession and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results in the other Division
  • Generally ensure that autonumbering respects the scoping of Accessions (e.g, using DataEntry, create Accessions in different scopes and ensure they're autonumbered as expected)

Looks good! I did run into some migration problems, but since that could be a test panel issue I will approve this, but it is something that should probably be looked into.

@emenslin emenslin requested a review from a team February 9, 2026 17:07
@bhumikaguptaa bhumikaguptaa self-requested a review February 9, 2026 21:50
Copy link
Collaborator

@bhumikaguptaa bhumikaguptaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Save the Data Entry record and ensure the record saves successfully
  • Reload the page and ensure Specify loads and still remains accessible
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Accession and ensure the record saves successfully
  • Ensure that the Accessions in different Divisions are independently auto-numbered (e.g., Accessions in different Divisions should not share the same autonumbering)
  • Save the Accession and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results in the other Division
  • Generally ensure that autonumbering respects the scoping of Accessions (e.g, using DataEntry, create Accessions in different scopes and ensure they're autonumbered as expected)

Everything worked as expected! I also came across a few migration errors while testing for the accession auto-numbering.

Image

@Iwantexpresso Iwantexpresso self-requested a review February 10, 2026 22:43
Copy link
Contributor

@Iwantexpresso Iwantexpresso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Save the Data Entry record and ensure the record saves successfully
  • Reload the page and ensure Specify loads and still remains accessible
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Data Entry record and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results.
  • Save the Accession and ensure the record saves successfully
  • Ensure that the Accessions in different Divisions are independently auto-numbered (e.g., Accessions in different Divisions should not share the same autonumbering)
  • Save the Accession and ensure the record saves successfully
  • Ensure that the value for the autonumbered field from Data Entry is skipped in the WorkBench upload results in the other Division
  • Generally ensure that autonumbering respects the scoping of Accessions (e.g, using DataEntry, create Accessions in different scopes and ensure they're autonumbered as expected)

I have tested the indecent division and found out that the independent autonomy based on divisions is not consistent

Screen.Recording.2026-02-10.at.4.46.47.PM.mov

this is a fresh version of the db and also there has been a weird crash in which it considered an already existing accession number as already existing even though they were from different divisions

trimmed.error.mov

here is the crash report if it give any insigne to the room of this problem
Edit: I have found out that this is happening after you attempt to autonumber into the test div twice in a row

Specify 7 Crash Report - 2026-02-10T22_58_30.487Z.txt

@github-project-automation github-project-automation bot moved this from 📋Back Log to Dev Attention Needed in General Tester Board Feb 10, 2026
melton-jason added a commit that referenced this pull request Feb 11, 2026
@melton-jason
Copy link
Contributor Author

melton-jason commented Feb 12, 2026

Thank you all for the reviews!

There some very subtle behavior going on behind the scenes to cause that behavior in your review @Iwantexpresso!

Ultimately, what's happening is tied to the fact that you can really only be logged into one collection as one user at a time for Specify across all tabs. That is, the Collection and User you are logged in as is shared across all tabs of Specify for that instance.
You can observe this behavior by opening two tabs of Specify, switching Collections in one, and refreshing the other. The Collection will appear to be "automatically" be switched to the other Collection, but the actual switching of Collections happened as soon as any tab of the Specify instance switches collection.

v7.11.4-prerelease_switch_collection.mov

So when you switch collections in one tab and navigate back to an older tab that is in some other collection, Specify will treat requests as having come from the collection of the prior (newer) tab.

Behind the scenes, Specify "globally" (with the perspective of the browser) manages which collection the user is signed in to via a Cookie, which is tab independent.

collection_id = int(request.COOKIES.get('collection', ''))

(This Cookie is set whenever the user explicitly chooses a Collection to login to. There's a backend helper function called set_collection_cookie you can look for usages for if you're curious about how this is implemented in the code!)

You can actually see which Collection you are "logged in to" by using your browser's developer tools. In the below demonstration of the bug, I inspect the Cookies present on the request made to the backend. Even though I appear to be in two separate Collections, because I last logged in to the Fish Collection (CollectionID = 32769) all request made from that point will also be made from the Fish Collection:

v7.11.4-prerelease_bts.mov

For more information, you can view the browsers docs on how to use their Developer Tools to inspect Cookies:
Chrome Dev Tools
Firefox Dev Tools

The general "expected" behavior is to explicitly switch Collections whenever you are dealing with more than one Collection:

v7.11.4-prerelease_expected.mov

There are probably a lot of nasty bugs that could arise if you expect to be logged into more than one Collection at a time for a Specify instance...

I will note, however, that this specific bug does not happen on main:

v7.11.4-prerelease_main.mov

The main difference between this branch and main is that we are storing the highest autonumbering value for the Collection that performed the autonumbering for 5 seconds. Because you are technically making the request within the same Collection and saving the other Accession within 5 seconds, autonumbering sees the first Accession Number and thinks it is in the same scope.

@specify/ux-testing
To summarize, the bug described in @Iwantexpresso review #7683 (review) occurs when:

  • You have a tab of Specify that is logged into some Collection
  • In another tab of the same instance you explicitly switch Collections to some other Collection in a different scope
  • In one of the two tabs you create a record that is autonumbered
  • Within 5 seconds, without changing Collections you create a record of the same table in the other tab that is also autonumbered

I can try and modify the Autonumbering code to first prioritize the scoping of the record being saved (i.e., use the field values of the record being saved) rather than the Collection the user is logged into (and fallback to the latter if the former can not be easily determined), though this may result in other subtle bugs because "easy to determine" is itself pretty difficult to determine 😅.

How often do you think this will happen in practice (a production instance)?

@emenslin
Copy link
Collaborator

  • You have a tab of Specify that is logged into some Collection
  • In another tab of the same instance you explicitly switch Collections to some other Collection in a different scope
  • In one of the two tabs you create a record that is autonumbered
  • Within 5 seconds, without changing Collections you create a record of the same table in the other tab that is also autonumbered

I can try and modify the Autonumbering code to first prioritize the scoping of the record being saved (i.e., use the field values of the record being saved) rather than the Collection the user is logged into (and fallback to the latter if the former can not be easily determined), though this may result in other subtle bugs because "easy to determine" is itself pretty difficult to determine 😅.

How often do you think this will happen in practice (a production instance)?

With all those points in mind I would imagine it is very unlikely for a user to run into this, and if fixing this one issue would likely cause other bugs I think it is probably not worth it to fix it, at least right now. I'd like to hear other opinions, especially @grantfitzsimmons, but personally I would think it's unlikely enough that it's not worth fixing.

@grantfitzsimmons
Copy link
Member

I agree with @emenslin, this is an edge case that is likely not to be encountered in production.

@melton-jason
Copy link
Contributor Author

melton-jason commented Feb 12, 2026

I would generally agree it is probably not likely to happen, but maybe that is just a result of being set in the Specify Way of Things.
Ideally and at a higher level, this edge case would be resolved if we ever do add support for being logged into more than one Collection at a given time, but that is probably not on the table any time soon.

We might be introducing much more prevalent bugs if this edge case is explicitly fixed.

I could decrease the threshold in which Specify will forget the highest autonumbering value in the same Scope relative to the Collection they're logged into (e.g., less than 5 seconds) to help mitigate this Issue, but it still has to be sufficiently long enough for instances (generally regardless of performance) to handle the genuine case of concurrent autonumbering with the WorkBench and Data Entry.

At the moment it seems like general sentiment is that the edge case is not going to be addressed, at least in the v7.12.0 release.

@grantfitzsimmons
Copy link
Member

@melton-jason @Iwantexpresso #7695

@grantfitzsimmons grantfitzsimmons merged commit 81966d3 into main Feb 13, 2026
14 checks passed
@grantfitzsimmons grantfitzsimmons deleted the v7.11.4-prerelease branch February 13, 2026 20:52
@github-project-automation github-project-automation bot moved this from Dev Attention Needed to ✅Done in General Tester Board Feb 13, 2026
@Iwantexpresso
Copy link
Contributor

Thank you all for the reviews!

There some very subtle behavior going on behind the scenes to cause that behavior in your review @Iwantexpresso!

Ultimately, what's happening is tied to the fact that you can really only be logged into one collection as one user at a time for Specify across all tabs. That is, the Collection and User you are logged in as is shared across all tabs of Specify for that instance. You can observe this behavior by opening two tabs of Specify, switching Collections in one, and refreshing the other. The Collection will appear to be "automatically" be switched to the other Collection, but the actual switching of Collections happened as soon as any tab of the Specify instance switches collection.

v7.11.4-prerelease_switch_collection.mov

So when you switch collections in one tab and navigate back to an older tab that is in some other collection, Specify will treat requests as having come from the collection of the prior (newer) tab.

Behind the scenes, Specify "globally" (with the perspective of the browser) manages which collection the user is signed in to via a Cookie, which is tab independent.

collection_id = int(request.COOKIES.get('collection', ''))

(This Cookie is set whenever the user explicitly chooses a Collection to login to. There's a backend helper function called set_collection_cookie you can look for usages for if you're curious about how this is implemented in the code!)

You can actually see which Collection you are "logged in to" by using your browser's developer tools. In the below demonstration of the bug, I inspect the Cookies present on the request made to the backend. Even though I appear to be in two separate Collections, because I last logged in to the Fish Collection (CollectionID = 32769) all request made from that point will also be made from the Fish Collection:

v7.11.4-prerelease_bts.mov

For more information, you can view the browsers docs on how to use their Developer Tools to inspect Cookies: Chrome Dev Tools Firefox Dev Tools

The general "expected" behavior is to explicitly switch Collections whenever you are dealing with more than one Collection:

v7.11.4-prerelease_expected.mov

There are probably a lot of nasty bugs that could arise if you expect to be logged into more than one Collection at a time for a Specify instance...

I will note, however, that this specific bug does not happen on main:

v7.11.4-prerelease_main.mov

The main difference between this branch and main is that we are storing the highest autonumbering value for the Collection that performed the autonumbering for 5 seconds. Because you are technically making the request within the same Collection and saving the other Accession within 5 seconds, autonumbering sees the first Accession Number and thinks it is in the same scope.

@specify/ux-testing To summarize, the bug described in @Iwantexpresso review #7683 (review) occurs when:

  • You have a tab of Specify that is logged into some Collection
  • In another tab of the same instance you explicitly switch Collections to some other Collection in a different scope
  • In one of the two tabs you create a record that is autonumbered
  • Within 5 seconds, without changing Collections you create a record of the same table in the other tab that is also autonumbered

I can try and modify the Autonumbering code to first prioritize the scoping of the record being saved (i.e., use the field values of the record being saved) rather than the Collection the user is logged into (and fallback to the latter if the former can not be easily determined), though this may result in other subtle bugs because "easy to determine" is itself pretty difficult to determine 😅.

How often do you think this will happen in practice (a production instance)?

yeah this totally makes sense. at first I did not fully process how uncommon it might actually be, but realistically speaking, The Pr itself still addresses its main purpose. I probably should've made it a comment than requesting changes, my apologies! still thank you for taking your time Explaining it in such detail it helps a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

Comments