Skip to content

fix(sqlite): make startup migrations concurrency-safe - #912

Merged
lklynet merged 3 commits into
mainfrom
t3code/fix-duplicate-sqlite-index
Sep 24, 2026
Merged

lklynet merged 3 commits into
mainfrom
t3code/fix-duplicate-sqlite-index

Conversation

@lklynet

@lklynet lklynet commented Sep 24, 2026

Copy link
Copy Markdown
Owner

What changed

SQLite startup now handles concurrent processes safely. It retries WAL setup after SQLITE_BUSY, rechecks the schema version inside an immediate migration transaction, and avoids write locks when the schema is already current. Startup also repairs missing search-index triggers, rebuilds outdated search documents, and creates the unique Lidarr artist index atomically while preserving the winning mappings.

Why

Concurrent Aurral starts could contend while setting WAL mode or applying the same migration and index changes, causing startup failures or inconsistent indexes. These changes serialize required writes and let up-to-date databases start without taking a write lock.

Scope checklist

  • This pull request has one clear purpose
  • I kept unrelated fixes, refactors, formatting changes, dependency updates, and features out of this pull request
  • If this adds a feature, I linked the approved feature request or included the Discord context in the Why section

Linked issue

None provided.

Testing

Added focused regression tests for concurrent startup on fresh and upgraded databases, migration rollback, startup with an existing writer, missing search-index triggers, and outdated search documents. Test execution was not reported in the supplied change details.

Release impact

  • Major: incompatible change
  • Minor: backward-compatible feature
  • Patch: backward-compatible fix
  • None: documentation, CI, tests, or internal-only change

@github-actions github-actions Bot added size:L 100-499 changed lines. bug Something is broken or behaving incorrectly. labels Sep 24, 2026
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Aurral preview image ready

This image was rebuilt from the latest push to this pull request. It will be replaced when you push another change.

docker pull ghcr.io/lklynet/aurral:pr-912

To test it with your existing Docker Compose setup:

  1. Back up your Aurral config.
  2. Temporarily change the Aurral service image to ghcr.io/lklynet/aurral:pr-912.
  3. Run docker compose pull aurral && docker compose up -d aurral.
  4. Exercise the behavior changed by this pull request.
  5. Restore the image reference that was configured before testing.

View the preview workflow run · Report a problem

Comment thread backend/config/library-search-index.js Outdated
@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: QUIET

Plan: Advanced

Run ID: 12e3e4ec-8dc3-4978-bac3-f94d333fd18e

📥 Commits

Reviewing files that changed from the base of the PR and between 561c5ce and 56d8438.

📒 Files selected for processing (1)
  • backend/config/db-sqlite.js

Included review availability: Your plan provides up to 4 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

SQLite startup now sets a busy timeout before WAL setup and retries WAL setup when SQLite reports a busy error. Schema migration rechecks the schema version inside its transaction. Lidarr artist mapping setup now removes duplicate mappings and creates a unique index when needed. Library search initialization checks FTS5 support, required triggers, and the stored index version before returning or rebuilding the index. Tests cover startup concurrency, index recovery, deduplication, and restoration after index creation failure.

Merge Risk: 🟡 Moderate · up to 56d84

A database held busy through WAL setup can still prevent the service from starting. Resolve or explicitly accept that startup limitation before merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: making SQLite startup migrations safe under concurrency.
Description check ✅ Passed The description explains what changed, why it changed, scope, testing areas, and release impact. It does not provide test execution results, but the description is otherwise complete and focused.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
backend/config/db-sqlite.js-31-31 (1)

31-31: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Continue startup when the WAL switch stays busy, and match extended busy codes.

better-sqlite3 enables extended result codes. As a result, error.code can be SQLITE_BUSY_RECOVERY or SQLITE_BUSY_SNAPSHOT. The strict !== "SQLITE_BUSY" check does not retry these codes and throws on the first attempt.

On the fifth busy attempt, the loop also rethrows and stops startup. WAL is a concurrency optimization, not a correctness requirement. If another process keeps the lock, startup should keep the current journal mode and continue. The next start can switch to WAL.

🛠️ Proposed fix
   } catch (error) {
-    if (error?.code !== "SQLITE_BUSY" || attempt === 4) throw error;
+    if (!String(error?.code || "").startsWith("SQLITE_BUSY")) throw error;
+    if (attempt === 4) {
+      console.warn("SQLite WAL setup skipped: database is busy");
+      break;
+    }
     Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
   }

Based on learnings: "setting PRAGMA journal_mode=WAL can fail with 'database is locked' … code should catch/ignore this specific failure and continue with schema creation and normal writes rather than aborting."

Source: Learnings


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: QUIET

Plan: Advanced

Run ID: b518afc3-38ca-4a7f-bdbe-dfac5e180585

📥 Commits

Reviewing files that changed from the base of the PR and between 492e600 and 5589c2e.

📒 Files selected for processing (7)
  • .tests/library/library-search-index.test.js
  • .tests/migration/lidarr-artist-index.test.js
  • .tests/migration/v2-migration.test.js
  • backend/config/db-sqlite.js
  • backend/config/library-search-index.js
  • backend/config/lidarr-artist-index.js
  • backend/config/schema-migration-v2.js
Files not reviewed due to moderation or processing errors (2)
  • backend/config/library-search-index.js
  • .tests/library/library-search-index.test.js

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@lklynet
lklynet force-pushed the t3code/fix-duplicate-sqlite-index branch from 5589c2e to c15de71 Compare September 24, 2026 16:40
@lklynet

lklynet commented Sep 24, 2026

Copy link
Copy Markdown
Owner Author

CodeRabbit WAL note: c15de71 now retries the extended SQLITE_BUSY_* codes. Startup still fails if WAL setup stays busy after the retries. Each attempt already waits the 5s busy timeout, and a database locked that long would fail the schema migration next anyway.

@github-actions github-actions Bot added size:L 100-499 changed lines. and removed size:L 100-499 changed lines. labels Sep 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
backend/config/library-search-index.js-216-221 (1)

216-221: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Return false before BEGIN IMMEDIATE when FTS5 is unavailable.

Line 216 returns early only when fts5Enabled is truthy. When FTS5 is unavailable, every startup therefore enters db.transaction(...).immediate().

The transaction only reads state and then returns false from createSearchSchema. It writes nothing. It still acquires a RESERVED lock on each start.

Assume another process holds a write transaction or runs a migration at the same time. Then BEGIN IMMEDIATE waits for the busy timeout and can throw SQLITE_BUSY, which fails startup on a no-op path. This contradicts the PR goal of avoiding write locks when no schema change is needed.

🔒️ Proposed fix
-  const current = hasCurrentSearchIndex();
-  if (fts5Enabled && current.hasIndex && current.hasTriggers && current.version === SEARCH_INDEX_VERSION) return true;
+  if (!fts5Enabled) return false;
+  const current = hasCurrentSearchIndex();
+  if (current.hasIndex && current.hasTriggers && current.version === SEARCH_INDEX_VERSION) return true;
 
   return db.transaction(() => {
     const { hasIndex, hasTriggers, version } = hasCurrentSearchIndex();
-    if (fts5Enabled && hasIndex && hasTriggers && version === SEARCH_INDEX_VERSION) return true;
-    if (fts5Enabled) {
-      db.exec(`
+    if (hasIndex && hasTriggers && version === SEARCH_INDEX_VERSION) return true;
+    db.exec(`
         DROP TRIGGER IF EXISTS library_search_documents_ai;
         ...
-      `);
-    }
+    `);

This follows the retrieved learnings on SQLite lock contention across processes.

Source: Learnings


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: QUIET

Plan: Advanced

Run ID: 29b78ea5-8bb7-4c51-896d-2a4a52417c0f

📥 Commits

Reviewing files that changed from the base of the PR and between 5589c2e and c15de71.

📒 Files selected for processing (3)
  • .tests/library/library-search-index.test.js
  • backend/config/db-sqlite.js
  • backend/config/library-search-index.js

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@github-actions github-actions Bot added size:L 100-499 changed lines. and removed size:L 100-499 changed lines. labels Sep 24, 2026
lklynet and others added 3 commits September 24, 2026 17:10
- Recheck schema and index state before applying migrations.
- Restore missing search triggers and rebuild outdated search documents.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lklynet
lklynet force-pushed the t3code/fix-duplicate-sqlite-index branch from 561c5ce to 56d8438 Compare September 24, 2026 17:14
@github-actions github-actions Bot added size:L 100-499 changed lines. and removed size:L 100-499 changed lines. labels Sep 24, 2026
@lklynet
lklynet merged commit 4a7dcc0 into main Sep 24, 2026
10 checks passed
@lklynet
lklynet deleted the t3code/fix-duplicate-sqlite-index branch September 24, 2026 17:32
@github-actions github-actions Bot mentioned this pull request Sep 24, 2026
5 tasks
@github-actions github-actions Bot added the nightly Available in the nightly image but not yet in a stable release. label Sep 24, 2026
@github-actions

Copy link
Copy Markdown

Available on nightly

A linked pull request was merged into main and is now included in the latest nightly build. Linked issues stay open until this change ships in a stable release.

docker pull ghcr.io/lklynet/aurral:nightly

vitorcsbrito added a commit to vitorcsbrito/aurral that referenced this pull request Sep 26, 2026
#25)

## What changed

PR numbers like lklynet#842 below refer to upstream `lklynet/aurral` pull
requests.

Brings the fork up to date with the parts of upstream `lklynet/aurral`
(2.9.0 → 2.10.0 and later, 102 commits since the fork point `7a42f9a6`)
that are worth having on top of the Postgres data layer. Upstream is not
merged wholesale: a trial merge produced 98 conflicted files because the
fork replaced SQLite, so every change was cherry-picked or hand-ported
with `(cherry picked from commit …)` / `Partial port of commit …`
references and adapted to the async `db.*` helpers.

**Security and auth**
- lklynet#792 `AUTH_PROXY_ENABLED=false` now wins over a configured proxy
header (the value is matched case-insensitively).
- lklynet#795 / lklynet#819 API-key-only requests can no longer create ownerless flows
or write user-owned data (favorites, play events,
Last.fm/ListenBrainz/Koito linking); they get 400/403. The same guard
now also covers playlist creation, import, the
Spotify/ListenBrainz/Last.fm imports and discover adoption.
- lklynet#870 Subsonic token auth works for every local user and follows
password changes. Credentials are stored encrypted with the settings key
in the new `users.subsonic_password` column (migration
`0005_users_subsonic_password`). Token auth needs the plaintext password
(MD5(password + salt)), so this is reversible encryption, the same
trade-off Navidrome makes.
- lklynet#613 identity-based OIDC, Google and Plex login and user lifecycle
(active/suspended/disabled, protected recovery admin, linked accounts,
15-minute re-auth for sensitive changes). Migration
`0006_user_identities` adds the tables/columns and runs upstream's
one-time backfill. Postgres adaptations: row locks for account adoption
and identity removal, 23505 mapped to 409, an in-memory mirror of
inactive owners so the download worker never queries per job. See the
commit message of c76db7b for the full list.

**Features**
- lklynet#741 reuse matching files already on disk before downloading.
- lklynet#846 per-playlist track availability with retry-missing.
- lklynet#883 listening-history toggle for flows and static playlists (More
menu).
- lklynet#889 webhook test button.
- lklynet#861 (+ lklynet#872, lklynet#876, lklynet#903) beets-backed matching engine for all
download sources, plus lklynet#899 album-only search fallback. The image gains
a Python venv with beets 2.14.1 at `/opt/aurral-matcher`, precompiled so
each match call starts warm. `/api/health` reports the matcher status,
and the Preview smoke test waits for its startup self-test.

**Fixes by area**
- Lidarr/library: lklynet#850 album requests stay monitored, lklynet#810 dedupe retry
jobs, lklynet#821/lklynet#854 Aurral ID markers read from native ID3 comments and
written to the grouping tag (no longer shown as Navidrome descriptions),
lklynet#848 Aurral-only artists stay out of Lidarr membership, lklynet#789 no library
scan per completed flow track, lklynet#845 (partial) every existing custom
format is listed in the Aurral profile, lklynet#799 (partial) structured log
for no-response Lidarr calls.
- Downloads/metadata: lklynet#793 yt-dlp channel validation, lklynet#890 yt-dlp node
runtime, lklynet#797 deemix reuses existing files, lklynet#852 slskd without API key,
lklynet#869 slskd missing download roots, lklynet#877 and lklynet#915 BrainzMash
caching/backoff and linked metadata first, lklynet#796 axios honours proxy env
vars.
- Playlists/activity: lklynet#893 large Spotify playlists (current `item`
wrapper, completeness check, no partial overwrite), lklynet#773 reused
downloads reconcile in Activity, lklynet#794 task queue counts beyond 500 rows.
- Media servers: Navidrome lklynet#774/lklynet#867/lklynet#887, Jellyfin lklynet#833 (settings save
no longer waits for library enumeration), Subsonic lklynet#791/lklynet#837.
- Discovery/other: lklynet#764, lklynet#778, lklynet#800, lklynet#798, lklynet#856, lklynet#808, lklynet#882 (jemalloc
decay, lower sharp/artwork concurrency).

**From lklynet#874 without the process split.** Background jobs stay
in-process: the fork's worker-thread scans and async Postgres already
remove the main-thread stalls lklynet#874 targets, and 11 processes would share
one Honker SQLite file and up to ~130 Postgres connections. Taken
instead:
- per-scope flow operation tokens (fixes a read-modify-write race);
- a hardened playlist mutation guard (partial-block rollback, release
always unblocks and prunes);
- `AURRAL_LIBRARY_SCAN_TIMEOUT_MS` (default 6 h) so a hung scan thread
is stopped instead of blocking every later scan.

**Playback-file retention (lklynet#842).** Automatic cleanup (flow refresh,
import sync, quality upgrade, fallback cleanup, download-folder
migration) no longer deletes files that a Plex, Navidrome or Jellyfin
playlist still references. Referenced files stay in place and are
retried on later library scans. If a service can't be checked, deletion
is deferred. Plex checks the server owner and every linked account,
using the fork's token-reconnect recovery. Navidrome needs an admin
account to see private playlists. Deliberate deletes and resets are
unchanged.

**Fixes from the final review** (several are upstream bugs too)
- `X-Forwarded-For` could spoof trust: with proxy auth on, a client
reaching Aurral directly could claim the proxy's address and sign in as
any user, even with `AUTH_PROXY_TRUSTED_IPS` set; with the local-network
bypass on, claiming `127.0.0.1` gave the sole admin. The allowlist now
checks the connecting address only, and the bypass needs every address
in the chain to be local.
- Any signed-in user could read or rotate the instance API key (which
authenticates as admin); both routes are now admin-only.
- An admin password reset now ends the account's sessions, websockets
and stream tokens. The protected recovery account can no longer be
demoted or deleted. Google login/exchange and Plex PIN creation share
the login rate limit.
- Stream and artwork routes served files without credentials on installs
with user accounts (or OIDC) but no `AUTH_PASSWORD`. They now follow the
same rule as the rest of the API.
- `updateUser` rewrote the whole row from an unlocked read (lost
updates); it now locks the row. Password logins go through
`recordPasswordLogin`, which only writes while the row still holds the
verified hash, so a login racing a password change cannot restore the
old password.
- JSON-backed stores (Plex/Navidrome/Jellyfin playlist pointers,
Plex/Spotify/scrobble connections) lost concurrent updates; writes are
now serialized. A Spotify token refresh can no longer resurrect a
cleared connection.
- lklynet#842 retention: an approved deletion clears the file's old retention
record, and Plex token rotation or sync errors no longer mark a cleanup
batch "usage unknown".
- Matching (lklynet#861): yt-dlp files were named by video id without tags, so
every yt-dlp download was rejected after downloading; titles like "Song
- Remastered 2009" were rejected or sent to review; "Live Forever"-style
titles were rejected as live versions on Soulseek/yt-dlp.
- lklynet#797: a deemix quality upgrade to the same path deleted the new
download and recorded the new tier on the old file.
- lklynet#741: on-disk reuse missed folders starting with "." ("...And Justice
for All").
- Flow record-history toggle in the flow menu called the shared-playlist
endpoint (upstream bug).
- `AURRAL_LIBRARY_SCAN_TIMEOUT_MS` above ~24.8 days made every scan time
out immediately; it is now capped.
- Pre-existing fork bugs found on the way: flow plans ignored the
owner's listening history (un-awaited profile), retry-registry writes
raced, disabling one news feed wiped all feeds and two news routes
answered `{}`.

**Fork-side fixes found while porting**
- Upstream's discovery refresh-loop fix (lklynet#764) read `.length` off a
promise on this fork, which silently disabled the missing-genre retry.
`discoveryNeedsRefresh` is now async and awaited.
- The lklynet#846 track-availability route returned before the async playlist
update finished. It now awaits it, as does the new lklynet#883 route.
- Upstream tests brought in by the picks were moved to the Postgres
harness. Upstream-only Playwright specs were dropped (the fork has no
e2e runner).

## Why

The fork was about 100 commits behind upstream, including security fixes
and features worth having. Porting commit by commit keeps the Postgres
conversion intact.

## Not ported (deliberately)

- **Jellyfin sync stack (lklynet#765/lklynet#812/lklynet#826)**: large; only needed with
Jellyfin.
- **lklynet#895 cancel downloads before playlist removal**: needs a redesign of
the download tracker on Postgres.
- **Library ownership chain (lklynet#756/lklynet#855/lklynet#917) and lklynet#768 available-only
default**: lklynet#768 is a product decision (it defaults to ON and hides
undownloaded albums).
- **lklynet#780 OpenSubsonic, lklynet#898 Navidrome stale-pointer recovery, lklynet#838
Navidrome prefix toggle, lklynet#835 unchanged-file scan skip, lklynet#790 per-artist
album fetch, lklynet#888, lklynet#884 logging, lklynet#900 UI lint, lklynet#817 Playwright**
- **SQLite-only changes** (lklynet#912, lklynet#824, lklynet#913 test tooling), the lklynet#874
process split, and upstream dependabot bumps (the fork's own dependabot
keeps its lockfile current).

## Known gaps

- The OIDC/SSO security review was done after the first ready-for-review
push (fixes above). Reviewed and fine: the OIDC flow (PKCE, state,
nonce, cookie-bound transaction and exchange code, status re-check),
Google and Plex link-only logins keyed by provider subject, session
lookup status checks, websocket auth, re-auth scoping, identity unlink
locking and migration 0006. Still open by design: with proxy auth
enabled and no `AUTH_PROXY_TRUSTED_IPS`, any client that can reach
Aurral may send the identity header (documented as required config).
- Reviewer notes left as-is: dead exports in
`weeklyFlowYtdlpSearch.js`/`weeklyFlowSoulseekSearch.js` (kept identical
to upstream); README and `docs/getting-started/docker.mdx` still point
at `ghcr.io/lklynet/aurral` rather than this fork's image; `lastfm.mdx`
still says an admin connects each user's Last.fm account.
- Docs were not built locally (no `docs/node_modules`); CI's docs build
covers it.

## Scope checklist

- [ ] This pull request has one clear purpose. Its purpose is syncing
upstream, but it bundles many upstream PRs.
- [ ] I kept unrelated fixes, refactors, formatting changes, dependency
updates, and features out of this pull request. It includes a few
fork-side fixes that the ports exposed (listed above).
- [ ] If this adds a feature, I linked the approved feature request or
included the Discord context in the Why section. Not applicable: these
are upstream features.

## Linked issue

None.

## Testing

Local environment: Node 26.8.2, PostgreSQL 18.6, ffmpeg 6.1.

- Baseline (`main`, 307c7dd): lint clean, unit 985/985, integration
57/57.
- Full run on 968385a (after the lklynet#613 OIDC port): lint clean, unit
1256/1256, integration 90/90, frontend build OK. CI green on that head.
- Full run on 5714d20: lint clean, unit 1271/1271, integration 90/90,
frontend build OK. The security-review commits after it (2e189c5,
d9adcd8) pass lint and the auth and user suites (unit 82/82,
integration 64/64; the two auth files again at 26/26 after the spoofing
tests were added). Every new test fails without its fix.
- Most review fixes add a regression test that fails without the fix and
passes with it. The exceptions are covered only by the existing suites:
the flow-menu history toggle, the deemix upgrade reuse, the
dotted-folder lookup, and the un-awaited history/registry writes.
- Not run: Docker image build and the Playwright smoke tests (no Docker
daemon or e2e harness here). CI's Preview workflow builds the image and
runs the matcher self-test.

## Release impact

- [ ] Major: incompatible change
- [x] Minor: backward-compatible feature
- [ ] Patch: backward-compatible fix
- [ ] None: documentation, CI, tests, or internal-only change

Database migrations: `0005_users_subsonic_password` (additive column)
and `0006_user_identities` (lklynet#613). They are applied at startup under the
existing advisory lock.

Upgrade notes (lklynet#613):
- Every session expires once; all users sign in again.
- OIDC users are now matched by issuer and subject. Before telling users
the upgrade is live, an admin should approve adoption of each existing
OIDC account (Settings > Users). Otherwise the first SSO sign-in creates
a new `-2` account.
- Subsonic token-only clients need the user to sign in to Aurral once
(or an admin password reset) before they work (lklynet#870).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_011txmpoBa1acyqWaPZUzyRo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Google and Plex sign-in, linked-account management, SSO-only
sign-in, and account status controls.
* Added per-playlist listening-history and track-availability settings,
with availability indicators and re-search actions.
* Added webhook testing and optional country codes for nearby-show
searches.
* **Improvements**
* Improved track matching and download review across sources, and
protects files still referenced by connected media-server playlists
during automatic cleanup.
* Supports slskd configurations without an API key and complete Spotify
playlist imports.
* Improved metadata lookups, playlist publishing, and account security.
* Added Navidrome path mappings for cleanup checks and public visibility
for newly created Navidrome playlists.
  * Prefers metadata-provider genres when available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Barbaros G. <tayyipgoren@gmail.com>
Co-authored-by: Lee Kelly <hello@leekelly.org>
Co-authored-by: Nikhil <nikhil.n.gohil@gmail.com>
Co-authored-by: ApolloVulpez <ambientskai@gmail.com>
Co-authored-by: skiinganchor <skiing_anchor.k4gaf@slmails.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Giacomo Sfratato <xbit18@hotmail.it>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is broken or behaving incorrectly. nightly Available in the nightly image but not yet in a stable release. size:L 100-499 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant