Skip to content

tsparser: report database usage outside services - #2604

Closed
marcuskohlberg wants to merge 2 commits into
mainfrom
tsparser-report-unattributed-db-usage
Closed

marcuskohlberg wants to merge 2 commits into
mainfrom
tsparser-report-unattributed-db-usage

Conversation

@marcuskohlberg

@marcuskohlberg marcuskohlberg commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Problem

In TS apps, using a database from code outside a service works under encore run and encore test, but fails once deployed, both on Encore Cloud and in self-hosted Docker images. Every query returns 500 with this database is not configured for use by this process.

Found while migrating Pingvin Share from NestJS to Encore: lib/prisma.ts used SQLDatabase.named("pingvin").connectionString.

Repro

// auth/db.ts
import { SQLDatabase } from "encore.dev/storage/sqldb";
export const DB = new SQLDatabase("pingvin", { migrations: "./migrations" });
// lib/db.ts: shared code outside any service
import { SQLDatabase } from "encore.dev/storage/sqldb";

const DB = SQLDatabase.named("pingvin");

export const connectionString = () => DB.connectionString;
export const countUsers = async () => (await DB.queryRow`SELECT COUNT(*)::int AS n FROM users`)!.n as number;
// auth/auth.ts
import { api } from "encore.dev/api";
import { countUsers, connectionString } from "../lib/db";

interface CountResponse {
  n: number;
  hasConnStr: boolean;
}

export const count = api({ expose: true, method: "GET", path: "/count" }, async (): Promise<CountResponse> => {
  return { n: await countUsers(), hasConnStr: connectionString().length > 0 };
});
Environment GET /count
encore run 200
Docker image (encore build docker) 500, this database is not configured for use by this process
Encore Cloud 500, same error

Encore Cloud repro app: deploy. Traces of the failed requests:

Calling the same query from inside auth/ returns 200 in the Docker image.

Root cause

In tsparser/src/legacymeta/mod.rs, a database usage outside any service built a ParseError with .parse_err(...) and dropped it, so the usage was silently ignored and auth.databases ended up empty in the metadata. Buckets, metrics and cache clusters use .err(...), which reports the error.

That empty list only matters once deployed:

  • encore run configures every database for the process (cli/daemon/run/runtime_config2.go), so it works locally.
  • encore build docker keeps only the databases in the hosted services' Service.Databases and drops the rest from the infra config (cli/daemon/export/infra_config.go).
  • Encore Cloud only links a service to the databases in its Service.Databases, and only linked databases end up in the runtime config.

Go apps aren't affected: the Go parser already rejects this with Infrastructure resources can only be referenced within services (E1814).

Fix

Report the error, with a hint on how to fix it. encore run, encore test and builds now fail right away:

error: cannot determine which service is accessing this database
 --> /tmp/sharedlib-db-repro/lib/db.ts:6:39
  |
6 | export const connectionString = () => DB.connectionString;
  |                                       ^^^^^^^^^^^^^^^^^^^
  |
  = help: databases can only be used within services. Use the database from the service that needs it.

Both documented ways of sharing a database keep working: declaring it in a shared module and referencing it from services, and SQLDatabase.named in another service. Only using the database from shared code is rejected.

This is a breaking change for TS apps that use a database from shared code. Those apps only work locally today and fail when deployed, so failing early seems better. A follow-up could attribute shared-code usage to the importing services instead, so the pattern just works.

Testing

  • New parser tests for database usage inside and outside a service. The outside test fails without the fix.
  • cargo test -p encore-tsparser passes, and clippy is clean.
  • No TS test apps in the repo use a database outside a service.
  • Ran the repro against a locally built TS parser: it now fails at parse time with the error above.

Summary by CodeRabbit

  • Bug Fixes
    • Database access outside a service now reports a diagnostic with guidance that databases must be used within services, rather than returning a parse error.
    • Database access inside a service continues to be recorded without errors.

Using a database from code outside a service (e.g. SQLDatabase.named in a
shared lib/ directory) built a ParseError but never reported it, so the
usage was silently dropped. encore run and encore test give the process
every database, so it worked locally, but deployed services only get the
databases attributed to them, and every query failed with "this database
is not configured for use by this process".

Report the error, with a hint matching the Go parser's, as is already done
for buckets, metrics and cache clusters.
@marcuskohlberg
marcuskohlberg requested a review from eandre October 10, 2026 08:36
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: QUIET
  • Plan: Advanced
  • Run ID: 8d58f266-9e9c-49d4-a898-99e61295dd53

📥 Commits

Reviewing files that changed from the base of the PR and between d5e6797 and 1b8ddb3.


📒 Files selected for processing (1)
  • tsparser/src/legacymeta/mod.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



Walkthrough

Database usage without an associated service now emits a span diagnostic with guidance and is not recorded. Tests check that usage inside a service is recorded without errors and usage outside a service emits an error.

Changes

Database usage diagnostics

Layer / File(s) Summary
Emit diagnostic and verify metadata
tsparser/src/legacymeta/mod.rs
Parsing emits a span diagnostic with help when database usage has no associated service, then skips recording that access. Test helpers expose diagnostic status, and tests check database usage inside and outside a service.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Merge Risk | ⚪ Minimal · up to 1b8dd

Merge Risk: ⚪ Minimal · up to 1b8dd

Using a database outside a service now produces a clear parse-time error with a hint. Previously this usage worked locally but failed after deployment. Database-sharing patterns through services are unaffected. No merge-blocking risk is evident.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 1b8dd

The change tightens validation without adding database access to any service. The normal build path rejects the error. Handling of failed WebAssembly results that still contain metadata remains unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The directly affected scope is parsing applications whose database usage cannot be associated with a service. The changed branch emits an error without adding database access to service metadata; broader tenant, credential, or infrastructure exposure is not established by the supplied evidence.

Trust Boundaries and Controls

  • observed — Source-file input reaches service attribution and diagnostic emission. The inspected build consumer rejects handler errors, while the WebAssembly producer exposes a failed status alongside possible metadata. Whether external clients reject that accompanying metadata remains a coverage gap, not an observed bypass.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: reporting database usage outside services.
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.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Match the docs on sharing databases instead of the Go phrasing about passing
a reference into a library.
@marcuskohlberg
marcuskohlberg force-pushed the tsparser-report-unattributed-db-usage branch from aea0088 to 1b8ddb3 Compare October 10, 2026 08:42
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.

1 participant