Skip to content

fix(cli): Use an in-memory database when cli.db won't open - #2070

Merged
BYK merged 1 commit into
mainfrom
fix/cli-db-memory-fallback
Nov 7, 2026
Merged

BYK merged 1 commit into
mainfrom
fix/cli-db-memory-fallback

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

cli.db only holds caches and settings, but if it couldn't be opened, every command failed. That included release.create and sourcemap.upload called from @sentry/bundler-plugins, even though a token passed to createSentrySDK({ token }) never comes from the database. The plugin swallows the error, so builds passed and sourcemaps were never uploaded.

Now, when getDatabase() can't open, set up, or migrate cli.db, it logs a warning and uses an in-memory database for the rest of the process. This covers a WAL file the WASM driver can't read (#2067, fixed separately in #2069), a config directory that can't be created, and a corrupt file. Shell completion already silences the read-only warning, and it now silences this one too, so pressing TAB doesn't print into the prompt. getRawDatabase() still throws the original error, so cli fix and the upgrade backup and restore never treat the in-memory copy as cli.db.

I left out the optional part of #2068, which would always use an in-memory database in library mode when a token is passed. With this fallback in place it isn't needed for correctness, and keeping cli.db saves region and project lookups on every build.

Reported by @sergical.

Fixes #2068

via @BYK.

--

View Session in Sentry

The local database only holds caches and settings, but a cli.db that couldn't be opened failed every command, including release and sourcemap uploads run from the bundler plugins. Warn and fall back to an in-memory database for the rest of the process instead. getRawDatabase() still throws, so cli fix and the upgrade backup never act on the in-memory copy.

Fixes #2068

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
@vercel

vercel Bot commented Nov 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
sentry-local Skipped Skipped Nov 7, 2026 12:35am UTC

Request Review

@BYK
BYK enabled auto-merge (squash) November 7, 2026 00:44
@BYK
BYK merged commit 9c6b9d0 into main Nov 7, 2026
27 checks passed
@BYK
BYK deleted the fix/cli-db-memory-fallback branch November 7, 2026 00:48
BYK added a commit that referenced this pull request Nov 7, 2026
Closes #1897.

`createSentrySDK()` calls now write no local state by default. They
still read what the CLI stored, so stored logins, defaults and cached
lookups in `cli.db` work, and so do `.sentryclirc` files and the custom
CA file. They never create or change `cli.db`, and the response cache
and version check are off. Pass `persist: true` to get the old behavior,
where SDK calls write state like the CLI.

How it works:
- The SDK sets an internal `SENTRY_CLI_NO_PERSISTENCE` flag in the
per-call env that `withEnv` already isolates, so the setting applies to
that call only.
- With the flag set, `getDatabase()` returns a read-only view of the
shared connection that only runs `SELECT` statements. Everything else is
dropped, including the `DELETE ... RETURNING` drains (telemetry queue,
completion queue) that read through `get()`/`all()`.
- When there's no `cli.db`, or it won't open (the WAL/driver cases from
#2069 and #2070, or a runtime with no SQLite driver), calls get a null
store and no warning. The null store skips schema setup entirely.
- Telemetry no longer depends on `persist`. It keeps its own opt-outs
(`SENTRY_CLI_NO_TELEMETRY`, `DO_NOT_TRACK`).

A new `env` option sets the environment each call starts from (default
`process.env`). On a server, pass `env` with only what the call needs,
so the server's own `SENTRY_DSN` doesn't change target resolution.

Behavior changes without `persist: true`:
- List commands reject `cursor: "next"`/`"prev"`, since the cursor stack
isn't written. Pass the returned `nextCursor` instead. `"first"` and raw
cursors work. The e2e test that pages with `cursor: "next"` now passes
`persist: true`.
- `getRawDatabase()` throws, so `cli fix` and `cli upgrade` need
`persist: true`.
- Opening an existing `cli.db` still runs the schema setup and
migrations any CLI run does, which can write on an older schema.

Also in here:
- The `.sentryclirc` caches are keyed by the active `SENTRY_CONFIG_DIR`,
since `env` can change it per call.
- The Spleen font loads on first use instead of at import.

This is a breaking change for SDK users, but the package is still `0.x`.
The bundler plugins pin `sentry@^0.45`, so they pick up the new default
only when they bump on purpose. That bump is the fix for the plugins'
`cli.db` failures. Module-level state shared between calls in one
process (the shared connection, the Sentry client, the custom-header and
region caches) is left to #1898.

<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:local%3Aweb%3A87622ce3671938950bc6e630 -->

--

[View Session in
Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3A87622ce3671938950bc6e630/?project=4510944073809921)

<!-- junior-session-footer:end -->

---------

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK added a commit to getsentry/sentry-javascript that referenced this pull request Nov 7, 2026
**Why:** Before `sentry` 0.49.0, every `createSentrySDK()` call opened
and wrote the CLI's local `cli.db`. When a build runs on a different
Node version than the one that created that file (for example through
`npx sentry`), the open fails with `SQLite3Error: unable to open
database file`. The build still passes, but release creation and source
map uploads fail silently. In 0.49.0, SDK calls write no local state by
default (getsentry/toolkit#2074) and fall back to running without
`cli.db` (getsentry/toolkit#2069, getsentry/toolkit#2070). This bumps
`@sentry/bundler-plugins`, `@sentry/remix` and `@sentry/react-router`,
plus the bundler plugin integration tests so the workspace resolves a
single version. None of them set `persist`, so the new default applies
as-is.

**How to review:** The four `package.json` ranges and the lockfile.
0.49.0 was published today, so pnpm added it to
`minimumReleaseAgeExclude`, as with the earlier first-party `@sentry/*`
entries there.

**Unsure about:** The `cloudflare-*-send-to-sentry` e2e apps pin
`sentry@~0.44.1` on their own. I left them alone because they're
separate test apps and don't go through the bundler plugin.

Closes #26197

<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:local%3Aweb%3A87622ce3671938950bc6e630 -->

--

[View Session in
Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3A87622ce3671938950bc6e630/?project=4510944073809921)

<!-- junior-session-footer:end -->

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK added a commit to getsentry/junior that referenced this pull request Nov 11, 2026
…3221)

## Problem

PR bodies credit people by name, so GitHub does not notify them. For
example, #3216 says "Reported by Cramer", and getsentry/toolkit#1955
says "Sergiy found a real problem". Some PRs get it right
(getsentry/toolkit#2070: "Reported by @sergical"), but only when a login
happens to be in context.

There are three causes:

- The `github-issues` skill gives `Reported by Alice.` as the example,
with a plain name. `github-code` has no rule for credit.
- The model has no way to map a person to a GitHub login. `userLookup`
maps a GitHub login to Slack only. The runtime resolves a linked login
only for the requester's `via` line.
- A parent agent writes the name into the brief, and the child copies
it. The #3216 brief said "Reported by Cramer; via @BYK.", so the PR
shows "via @BYK." twice, because the runtime also adds it.

## Fix

- `userLookup` Slack results now include `linked_identities`: the
verified handles of other accounts that the person linked, such as `{
provider: "github", handle: "dcramer" }`. Only account-linking flows
write these, so the handles are verified.
- `github-code` and `github-issues` now say to credit other people by
`@login`. They get the login from `linked_identities`, then from a
GitHub link in Slack `profile_fields`. Otherwise they use the name, and
they never guess a login. A delegated brief carries the `@login`.
`github-code` also says not to write the requester `via` line.
- `github-issues` now strips "Slack user mentions" instead of all
"@mentions", so the session-framing rule does not remove GitHub logins.

## Remaining risk

People who have not linked GitHub and have no GitHub link in their Slack
profile still get their name, not a mention. No eval covers the credit
wording yet.

<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:local%3Aweb%3Afb1f20a0ae8da9a914242b49 -->

--

[View Session in
Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3Afb1f20a0ae8da9a914242b49/?project=4510944073809921)

<!-- junior-session-footer:end -->

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
Preview — d0ab77cf Deployed Nov 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Don't fail commands when the local database won't open

1 participant