2251 - Resolve server deactivation error for servers with email teams#2253
Merged
crivetimihai merged 1 commit intomainfrom Jan 21, 2026
Merged
2251 - Resolve server deactivation error for servers with email teams#2253crivetimihai merged 1 commit intomainfrom
crivetimihai merged 1 commit intomainfrom
Conversation
385e97e to
6a2e276
Compare
This commit fixes a bug where deactivating a virtual server associated with an email notification team would fail with a database error. The root cause was the use of `joinedload` to fetch the `email_team` relationship when retrieving the server to be updated. This resulted in a `LEFT OUTER JOIN` in the underlying SQL query. When the query also included a `FOR UPDATE` clause to lock the server row, PostgreSQL raised a `FeatureNotSupported` error because it cannot apply a lock to the nullable side of an outer join. This fix changes the SQLAlchemy loading strategy from `joinedload` to `selectinload` for the `DbServer.email_team` relationship within the `set_server_state` method. `selectinload` resolves the issue by loading the relate `email_team` in a separate `SELECT` statement, thus avoiding the problematic `JOIN` in the initial `SELECT ... FOR UPDATE` query. Additionally, comprehensive unit tests have been added for both the `ServerService` and the admin panel routes to cover server activation, deactivation, and to verify that the fix works as expected, preventing future regressions. Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
6a2e276 to
708e24e
Compare
crivetimihai
approved these changes
Jan 21, 2026
010gvr
pushed a commit
to 010gvr/mcp-context-forge
that referenced
this pull request
Jan 23, 2026
…IBM#2253) This commit fixes a bug where deactivating a virtual server associated with an email notification team would fail with a database error. The root cause was the use of `joinedload` to fetch the `email_team` relationship when retrieving the server to be updated. This resulted in a `LEFT OUTER JOIN` in the underlying SQL query. When the query also included a `FOR UPDATE` clause to lock the server row, PostgreSQL raised a `FeatureNotSupported` error because it cannot apply a lock to the nullable side of an outer join. This fix changes the SQLAlchemy loading strategy from `joinedload` to `selectinload` for the `DbServer.email_team` relationship within the `set_server_state` method. `selectinload` resolves the issue by loading the relate `email_team` in a separate `SELECT` statement, thus avoiding the problematic `JOIN` in the initial `SELECT ... FOR UPDATE` query. Additionally, comprehensive unit tests have been added for both the `ServerService` and the admin panel routes to cover server activation, deactivation, and to verify that the fix works as expected, preventing future regressions. Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
This was referenced Jan 23, 2026
Closed
kcostell06
pushed a commit
to kcostell06/mcp-context-forge
that referenced
this pull request
Feb 24, 2026
…IBM#2253) This commit fixes a bug where deactivating a virtual server associated with an email notification team would fail with a database error. The root cause was the use of `joinedload` to fetch the `email_team` relationship when retrieving the server to be updated. This resulted in a `LEFT OUTER JOIN` in the underlying SQL query. When the query also included a `FOR UPDATE` clause to lock the server row, PostgreSQL raised a `FeatureNotSupported` error because it cannot apply a lock to the nullable side of an outer join. This fix changes the SQLAlchemy loading strategy from `joinedload` to `selectinload` for the `DbServer.email_team` relationship within the `set_server_state` method. `selectinload` resolves the issue by loading the relate `email_team` in a separate `SELECT` statement, thus avoiding the problematic `JOIN` in the initial `SELECT ... FOR UPDATE` query. Additionally, comprehensive unit tests have been added for both the `ServerService` and the admin panel routes to cover server activation, deactivation, and to verify that the fix works as expected, preventing future regressions. Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🐛 Bug-fix PR
📌 Summary
This PR fixes a critical bug that prevented the deactivation of a virtual server when it was associated with an email notification team. The action would fail due to a database error, making it impossible to disable certain servers through the Admin UI or API. This fix ensures the deactivation process is robust and reliable, regardless of the server's associations
Closes #2251
🔁 Reproduction Steps
🐞 Root Cause
The root cause of the issue was a psycopg.errors.FeatureNotSupported error from PostgreSQL, stating: "FOR UPDATE cannot be applied to the nullable side of an outer join".
This occurred because the set_server_state service method used SQLAlchemy's joinedload strategy to fetch the server along with its related email_team. This created a LEFT OUTER JOIN in the SQL query. When the database
transaction attempted to lock the server row for the update using FOR UPDATE, it conflicted with the outer join, as PostgreSQL does not support locking on the nullable side of such joins.
💡 Fix Description
The fix replaces the data loading strategy for the email_team relationship within
ServerService. Thejoinedloadhas been replaced withselectinload.selectinload resolves the problem by issuing a separate
SELECTstatement to load the related email_team after the server has been retrieved. This decouples the queries, avoiding the problematicLEFT OUTER JOINin the initialSELECT ... FOR UPDATEstatement and allowing the row lock to be acquired without error.In addition to the core fix, this PR introduces comprehensive unit tests for the
set_server_statemethod and the corresponding admin API endpoint. These tests cover activation, deactivation, permission handling, andspecifically verify that the fix works correctly when an email team is present, preventing future regressions.
🧪 Verification
make lintmake testmake coverage✅ Checklist
make black isort pre-commit)