Skip to content

[management] Fix/delete groups without lock#5012

Merged
pascal-fischer merged 9 commits intomainfrom
fix/delete-groups-without-lock
Dec 31, 2025
Merged

[management] Fix/delete groups without lock#5012
pascal-fischer merged 9 commits intomainfrom
fix/delete-groups-without-lock

Conversation

@pascal-fischer
Copy link
Copy Markdown
Collaborator

@pascal-fischer pascal-fischer commented Dec 30, 2025

Describe your changes

Issue ticket number and link

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • Bug Fixes

    • Early-exit when no groups are eligible for deletion to avoid unnecessary work and noisy errors.
  • Performance

    • Per-store configurable transaction timeouts to prevent long-running DB transactions and improve reliability.
  • Tests

    • New test covering transaction timeout behavior.
  • Other

    • Added timing logs reporting total durations for sync and login operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

Adds deferred duration logging to gRPC handlers, reduces lock strength and early-returns in group deletion when nothing to delete, and introduces per-store transaction timeouts with deadline-aware logging and cancellation in the SQL store.

Changes

Cohort / File(s) Summary
gRPC server logging
management/internals/shared/grpc/server.go
Added deferred timing logs in Sync and Login to record total request durations.
Group deletion logic
management/server/group.go
Lowered group fetch lock from Update to None; added guard to return early when no deletable groups are collected (skips deletions and network serial increment).
SQL store transaction timeout
management/server/store/sql_store.go, management/server/store/sql_store_test.go
Added transactionTimeout time.Duration on SqlStore, read NB_STORE_TRANSACTION_TIMEOUT (default 5m); ExecuteInTransaction uses a timeout-bound context for Begin/tx, logs warnings and stack traces on deadline exceed during operation or commit; updated test to exercise timeout behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant GRPC as gRPC Handler (Sync/Login)
  participant Store as SqlStore.ExecuteInTransaction
  participant DB as Database (tx)

  Client->>GRPC: Send Sync/Login request
  GRPC->>GRPC: record reqStart (deferred duration log)
  GRPC->>Store: ExecuteInTransaction(ctx, fn)
  note right of Store `#f0f7ff`: create timeoutCtx (s.transactionTimeout)
  Store->>DB: BEGIN (with timeoutCtx)
  DB-->>Store: tx
  Store->>DB: run operations using tx
  alt completes before timeout
    DB-->>Store: operation success
    Store->>DB: COMMIT
    DB-->>Store: commit success
    Store-->>GRPC: return success
  else deadline exceeded
    DB-->>Store: context deadline exceeded / error
    Store->>Store: log warning + stack trace (elapsed)
    Store-->>GRPC: return error
  end
  GRPC->>GRPC: emit deferred duration log
  GRPC-->>Client: respond
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇
I timed my hops from root to leaf,
Watched transactions stall — then brief.
Locks softened, timers set just right,
I scribbled logs beneath moonlight.
Code carrots crunch — a cozy bite! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description follows the template structure but provides no substantive details about the changes, issue reference, or implementation explanation. Add a clear explanation of what was changed and why (e.g., describe the lock reduction and guard condition in DeleteGroups). Include the issue ticket number and link, and explain the purpose of the other changes (transaction timeout, logging).
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title directly corresponds to the main change in management/server/group.go: reducing lock strength from Update to None when deleting groups.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9736fa9 and 08f1bf3.

📒 Files selected for processing (2)
  • management/internals/shared/grpc/server.go
  • management/server/store/sql_store_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • management/internals/shared/grpc/server.go
  • management/server/store/sql_store_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Management / Unit (amd64, mysql)
  • GitHub Check: Client / Unit (386)
  • GitHub Check: Relay / Unit (386)
  • GitHub Check: Management / Integration (amd64, postgres)
  • GitHub Check: Management / Unit (amd64, postgres)
  • GitHub Check: Management / Benchmark (API) (amd64, sqlite)
  • GitHub Check: Management / Integration (amd64, sqlite)
  • GitHub Check: Management / Benchmark (API) (amd64, postgres)
  • GitHub Check: Relay / Unit (amd64, -race)
  • GitHub Check: Client / Unit (amd64)
  • GitHub Check: Management / Unit (amd64, sqlite)
  • GitHub Check: Client (Docker) / Unit
  • GitHub Check: Management / Benchmark (amd64, postgres)
  • GitHub Check: Management / Benchmark (amd64, sqlite)
  • GitHub Check: JS / Lint
  • GitHub Check: release_ui
  • GitHub Check: release
  • GitHub Check: FreeBSD Port / Build & Test
  • GitHub Check: Client / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: Android / Build
  • GitHub Check: iOS / Build
  • GitHub Check: Windows
  • GitHub Check: Linux

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
management/server/group.go (1)

428-443: Potential TOCTOU race condition with None locking.

Lowering the locking strength from Update to None during group validation introduces a time-of-check to time-of-use window. Between validation (line 436) and deletion (line 449), another transaction could link the group to a resource, policy, or other entity. The validation would pass, but the group should no longer be deletable.

Consider whether this race condition is acceptable in your system, or if you should restore at least Read locking during validation.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96cdd56 and c60b109.

📒 Files selected for processing (3)
  • management/internals/shared/grpc/server.go
  • management/server/group.go
  • management/server/store/sql_store.go
🧰 Additional context used
🧬 Code graph analysis (3)
management/internals/shared/grpc/server.go (1)
monotime/time.go (1)
  • Since (33-35)
management/server/group.go (1)
management/server/store/store.go (1)
  • LockingStrengthNone (47-47)
management/server/store/sql_store.go (1)
management/server/telemetry/store_metrics.go (1)
  • StoreMetrics (11-18)
🪛 GitHub Check: Management / Benchmark (API) (amd64, postgres)
management/server/store/sql_store.go

[failure] 40-40:
"github.com/netbirdio/netbird/shared/sshauth" imported and not used

🪛 GitHub Check: Management / Benchmark (API) (amd64, sqlite)
management/server/store/sql_store.go

[failure] 40-40:
"github.com/netbirdio/netbird/shared/sshauth" imported and not used

🪛 GitHub Check: Management / Integration (amd64, postgres)
management/server/store/sql_store.go

[failure] 40-40:
"github.com/netbirdio/netbird/shared/sshauth" imported and not used

🪛 GitHub Check: Management / Integration (amd64, sqlite)
management/server/store/sql_store.go

[failure] 40-40:
"github.com/netbirdio/netbird/shared/sshauth" imported and not used

🪛 GitHub Check: Management / Unit (amd64, sqlite)
management/server/store/sql_store.go

[failure] 40-40:
"github.com/netbirdio/netbird/shared/sshauth" imported and not used

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (22)
  • GitHub Check: Client / Unit (386)
  • GitHub Check: Management / Unit (amd64, postgres)
  • GitHub Check: Management / Benchmark (amd64, postgres)
  • GitHub Check: Management / Unit (amd64, mysql)
  • GitHub Check: Relay / Unit (386)
  • GitHub Check: Management / Benchmark (amd64, sqlite)
  • GitHub Check: Client / Unit (amd64)
  • GitHub Check: Relay / Unit (amd64, -race)
  • GitHub Check: Client (Docker) / Unit
  • GitHub Check: Darwin
  • GitHub Check: Linux
  • GitHub Check: Windows
  • GitHub Check: release
  • GitHub Check: Android / Build
  • GitHub Check: FreeBSD Port / Build & Test
  • GitHub Check: release_ui_darwin
  • GitHub Check: Client / Unit
  • GitHub Check: release_ui
  • GitHub Check: iOS / Build
  • GitHub Check: Client / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: JS / Lint
🔇 Additional comments (6)
management/internals/shared/grpc/server.go (2)

230-232: LGTM! Good observability improvement.

The deferred duration logging for the Sync operation enhances observability without affecting the existing control flow.


568-573: LGTM! Consistent timing log.

The Login duration logging is consistent with the Sync operation timing pattern and provides valuable observability.

management/server/group.go (1)

445-447: Good optimization with early return guard.

The early return when no groups are deletable prevents unnecessary transaction work and avoids incrementing the network serial when no changes occur. This is a clean optimization.

management/server/store/sql_store.go (3)

2901-2902: Using context.Background() ignores caller's context cancellation.

The transaction timeout context is created from context.Background() instead of the passed ctx parameter. This means if the caller's context is cancelled, the transaction will continue running for up to 5 minutes, ignoring the cancellation signal.

This may be intentional to prevent transaction interruption, but it's unusual behavior. If this is by design, consider documenting why the caller's context is ignored. Otherwise, consider creating the timeout from the caller's context: timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Minute).


2936-2944: Good timeout-aware error handling with stack traces.

The timeout error handling after the operation is well-implemented. The defensive check for both the operation error and the timeout context error ensures timeout scenarios are properly logged with stack traces for debugging.


2954-2967: Correct nil return on successful commit.

The explicit return nil on Line 2967 correctly ensures that a successful transaction returns no error, rather than potentially propagating a stale error value. The timeout-aware error handling on commit is also well-implemented.

Comment thread management/server/store/sql_store.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c60b109 and 751b2f9.

📒 Files selected for processing (1)
  • management/server/store/sql_store.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: Management / Integration (amd64, postgres)
  • GitHub Check: Management / Benchmark (API) (amd64, postgres)
  • GitHub Check: Management / Benchmark (API) (amd64, sqlite)
  • GitHub Check: Management / Integration (amd64, sqlite)
  • GitHub Check: Management / Benchmark (amd64, postgres)
  • GitHub Check: Management / Unit (amd64, postgres)
  • GitHub Check: Client (Docker) / Unit
  • GitHub Check: Relay / Unit (amd64, -race)
  • GitHub Check: Management / Unit (amd64, sqlite)
  • GitHub Check: Management / Unit (amd64, mysql)
  • GitHub Check: Signal / Unit (amd64)
  • GitHub Check: Client / Unit (amd64)
  • GitHub Check: Client / Unit (386)
  • GitHub Check: Management / Benchmark (amd64, sqlite)
  • GitHub Check: Relay / Unit (386)
  • GitHub Check: release_ui
  • GitHub Check: release
  • GitHub Check: FreeBSD Port / Build & Test
  • GitHub Check: release_ui_darwin
  • GitHub Check: Darwin
  • GitHub Check: Windows
  • GitHub Check: Linux
  • GitHub Check: iOS / Build
  • GitHub Check: Android / Build
  • GitHub Check: Client / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: JS / Lint

Comment thread management/server/store/sql_store.go Outdated
Comment thread management/server/store/sql_store.go
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
management/server/store/sql_store.go (2)

2910-2915: Critical: ExecuteInTransaction should derive its timeout from the passed ctx, not context.Background().

ExecuteInTransaction currently does:

timeoutCtx, cancel := context.WithTimeout(context.Background(), s.transactionTimeout)

This breaks the context chain and ignores caller cancellation, deadlines, and values (tracing, request IDs, etc.). It also means that if the caller’s ctx is already cancelled or has a shorter deadline, that is not respected.

You should derive the timeout context from ctx and also handle the “no/invalid timeout” case explicitly. For example:

- timeoutCtx, cancel := context.WithTimeout(context.Background(), s.transactionTimeout)
+ var (
+     timeoutCtx context.Context
+     cancel     context.CancelFunc
+ )
+ if s.transactionTimeout <= 0 {
+     // No store-level timeout; still honor caller cancellation.
+     timeoutCtx, cancel = context.WithCancel(ctx)
+ } else {
+     timeoutCtx, cancel = context.WithTimeout(ctx, s.transactionTimeout)
+ }
  defer cancel()

This preserves caller semantics while still enforcing the store‑level timeout.

Go stdlib `context.WithTimeout` semantics when the parent context is already cancelled or has an earlier deadline, and recommended practice for composing timeouts with a parent context.

2949-2951: Fix timeout log messages to reflect the configured duration instead of hardcoded “5 minute timeout”.

Both timeout warning logs still say "transaction exceeded 5 minute timeout" even though the actual timeout comes from s.transactionTimeout and can be overridden via NB_STORE_TRANSACTION_TIMEOUT. This can be misleading when operators tune the timeout.

Suggested change:

- if errors.Is(err, context.DeadlineExceeded) || errors.Is(timeoutCtx.Err(), context.DeadlineExceeded) {
-     log.WithContext(ctx).Warnf("transaction exceeded 5 minute timeout after %v, stack: %s", time.Since(startTime), debug.Stack())
- }
+ if errors.Is(err, context.DeadlineExceeded) || errors.Is(timeoutCtx.Err(), context.DeadlineExceeded) {
+     log.WithContext(ctx).Warnf("transaction exceeded %v timeout after %v, stack: %s", s.transactionTimeout, time.Since(startTime), debug.Stack())
+ }

and similarly for the commit‑timeout branch:

- log.WithContext(ctx).Warnf("transaction commit exceeded 5 minute timeout after %v, stack: %s", time.Since(startTime), debug.Stack())
+ log.WithContext(ctx).Warnf("transaction commit exceeded %v timeout after %v, stack: %s", s.transactionTimeout, time.Since(startTime), debug.Stack())
Confirm that `time.Duration` formatting (e.g., `%v` on `s.transactionTimeout`) produces human-readable output suitable for logs in Go.

Also applies to: 2963-2969

🧹 Nitpick comments (2)
management/server/store/sql_store.go (1)

58-68: Per‑store transaction timeout wiring looks good; consider guarding non‑positive values.

The new transactionTimeout field is correctly initialized in NewSqlStore (including the skipMigration path) and logged, so all SqlStore instances share a consistent timeout.

One small hardening you might consider: if NB_STORE_TRANSACTION_TIMEOUT parses to <= 0, either:

  • fall back to the default 5 * time.Minute, or
  • treat it explicitly as “no timeout” and document/log that behavior.

That avoids accidental 0s / negative misconfig causing transactions to immediately time out.

Also applies to: 89-96, 112-115, 133-133

management/server/store/sql_store_test.go (1)

8-8: Test is solid for SQLite; consider minor robustness for multi-driver future-proofing.

The new TestSqlStore_ExecuteInTransaction_Timeout correctly verifies that:

  • NB_STORE_TRANSACTION_TIMEOUT is parsed and applied (1 second),
  • a transaction exceeding that timeout fails with an error.

The test uses errors.Is(err, context.DeadlineExceeded) which is the correct pattern. However, across different SQL drivers (Postgres, MySQL, SQLite), the exact error returned from Commit() on context timeout can vary: Postgres may surface DB-specific errors, MySQL behavior is inconsistent across drivers, and only SQLite with proper context support reliably returns DeadlineExceeded. Since this test currently targets SQLite only, the assertion works as-is, but if you plan to extend this to other engines, consider broadening the check:

- require.Error(t, err)
- assert.True(t, errors.Is(err, context.DeadlineExceeded), "expected context.DeadlineExceeded error, got: %v", err)
+ require.Error(t, err)
+ assert.True(t, errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled),
+     "expected context deadline or cancel error, got: %v", err)

This makes the test more resilient if run against multiple database engines in the future.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 751b2f9 and 072a134.

📒 Files selected for processing (2)
  • management/server/store/sql_store.go
  • management/server/store/sql_store_test.go
🧰 Additional context used
🧬 Code graph analysis (2)
management/server/store/sql_store.go (1)
management/server/telemetry/store_metrics.go (1)
  • StoreMetrics (11-18)
management/server/store/sql_store_test.go (2)
management/server/store/store.go (1)
  • Store (50-208)
management/server/store/sql_store.go (1)
  • SqlStore (59-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: Client / Unit (amd64)
  • GitHub Check: Management / Benchmark (API) (amd64, sqlite)
  • GitHub Check: Management / Integration (amd64, postgres)
  • GitHub Check: Signal / Unit (386)
  • GitHub Check: Management / Integration (amd64, sqlite)
  • GitHub Check: Management / Benchmark (API) (amd64, postgres)
  • GitHub Check: Management / Unit (amd64, sqlite)
  • GitHub Check: Management / Unit (amd64, postgres)
  • GitHub Check: Client / Unit (386)
  • GitHub Check: Management / Benchmark (amd64, sqlite)
  • GitHub Check: Management / Unit (amd64, mysql)
  • GitHub Check: Relay / Unit (386)
  • GitHub Check: Management / Benchmark (amd64, postgres)
  • GitHub Check: Relay / Unit (amd64, -race)
  • GitHub Check: Client (Docker) / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: release
  • GitHub Check: FreeBSD Port / Build & Test
  • GitHub Check: release_ui_darwin
  • GitHub Check: release_ui
  • GitHub Check: Linux
  • GitHub Check: Darwin
  • GitHub Check: Windows
  • GitHub Check: Client / Unit
  • GitHub Check: iOS / Build
  • GitHub Check: Android / Build
  • GitHub Check: JS / Lint

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
management/server/store/sql_store.go (1)

89-95: Consider adding timeout validation and parse error logging.

The current implementation silently falls back to the default timeout if parsing fails or if an invalid timeout is provided. Consider these optional improvements for better robustness:

  1. Log a warning when parsing fails so operators are aware their configuration is ignored
  2. Validate that the parsed timeout is positive (reject zero or negative values)
🔎 Suggested enhancement
 transactionTimeout := 5 * time.Minute
 if v := os.Getenv("NB_STORE_TRANSACTION_TIMEOUT"); v != "" {
 	if parsed, err := time.ParseDuration(v); err == nil {
+		if parsed <= 0 {
+			log.WithContext(ctx).Warnf("Invalid NB_STORE_TRANSACTION_TIMEOUT %v (must be positive), using default %v", parsed, transactionTimeout)
+		} else {
 			transactionTimeout = parsed
+		}
+	} else {
+		log.WithContext(ctx).Warnf("Failed to parse NB_STORE_TRANSACTION_TIMEOUT=%q: %v, using default %v", v, err, transactionTimeout)
 	}
 }
 log.WithContext(ctx).Infof("Setting transaction timeout to %v", transactionTimeout)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 072a134 and 9736fa9.

📒 Files selected for processing (2)
  • management/server/store/sql_store.go
  • management/server/store/sql_store_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • management/server/store/sql_store_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
management/server/store/sql_store.go (2)
monotime/time.go (2)
  • Now (28-31)
  • Since (33-35)
management/server/telemetry/store_metrics.go (1)
  • StoreMetrics (11-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: Management / Benchmark (API) (amd64, postgres)
  • GitHub Check: Management / Integration (amd64, postgres)
  • GitHub Check: Management / Benchmark (API) (amd64, sqlite)
  • GitHub Check: Management / Integration (amd64, sqlite)
  • GitHub Check: Signal / Unit (386)
  • GitHub Check: Relay / Unit (386)
  • GitHub Check: Management / Benchmark (amd64, sqlite)
  • GitHub Check: Management / Unit (amd64, sqlite)
  • GitHub Check: Management / Unit (amd64, mysql)
  • GitHub Check: Relay / Unit (amd64, -race)
  • GitHub Check: Management / Unit (amd64, postgres)
  • GitHub Check: Management / Benchmark (amd64, postgres)
  • GitHub Check: Client / Unit (amd64)
  • GitHub Check: Signal / Unit (amd64)
  • GitHub Check: Client / Unit (386)
  • GitHub Check: Client (Docker) / Unit
  • GitHub Check: Client / Unit
  • GitHub Check: release_ui_darwin
  • GitHub Check: release
  • GitHub Check: release_ui
  • GitHub Check: FreeBSD Port / Build & Test
  • GitHub Check: Linux
  • GitHub Check: Windows
  • GitHub Check: Darwin
  • GitHub Check: iOS / Build
  • GitHub Check: Android / Build
  • GitHub Check: JS / Lint
  • GitHub Check: Client / Unit
🔇 Additional comments (1)
management/server/store/sql_store.go (1)

2910-2976: Transaction timeout implementation looks good.

The changes correctly implement configurable transaction timeouts with proper timeout detection and logging. The timeout value is now correctly referenced in log messages (addressing the past review comment).

Note: The use of context.Background() at line 2910 (rather than deriving from the passed ctx parameter) is a known limitation that was previously discussed and will be addressed in a future improvement per maintainer feedback.

@sonarqubecloud
Copy link
Copy Markdown

@pascal-fischer pascal-fischer merged commit 7ac65bf into main Dec 31, 2025
40 of 41 checks passed
@pascal-fischer pascal-fischer deleted the fix/delete-groups-without-lock branch December 31, 2025 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants