Which Cloudflare product(s) does this pertain to?
vitest-pool-workers
What versions & operating system are you using?
@cloudflare/vitest-pool-workers@0.12.20 (latest, verified — also reproduced on 0.12.19)
miniflare@4.20260301.1
wrangler@4.71.0
- macOS, Node 22
Describe the Bug
When a worker uses secrets_store_secrets in wrangler.jsonc, vitest-pool-workers correctly reads the config and creates the service bindings (with .get()), but the backing secrets store is always empty. Calling env.SECRET.get() throws Error: Secret "..." not found.
Root cause: secretsStorePersist is a shared Miniflare option, but vitest-pool-workers only passes a fixed set of shared options:
// pool/index.mjs line 7518
var SHARED_MINIFLARE_OPTIONS = {
log: mfLog,
verbose: true,
handleRuntimeStdio,
unsafeStickyBlobs: true
};
secretsStorePersist is not included. Even when specified in the vitest config's miniflare block, it's parsed as a per-worker option and silently ignored. Without it, Miniflare falls back to a fresh temporary directory, so the backing KV is always empty.
This is different from d1Persist, kvPersist, r2Persist, etc., which also aren't in SHARED_MINIFLARE_OPTIONS — but those are typically seeded in test setup (e.g., applyD1Migrations). There's no equivalent API to seed the secrets store from within a test.
Expected behavior
Either:
secretsStorePersist should be forwarded to the Miniflare constructor (like other persist options), OR
- There should be a
cloudflare:test API to seed secrets store values (analogous to applyD1Migrations), OR
- The docs should mention this limitation under known issues
Workaround
Use a wrangler environment that omits secrets_store_secrets, provide the secret as a plain string binding via miniflare.bindings, and handle both types in application code:
// vitest.config.ts
wrangler: { configPath: "./wrangler.jsonc", environment: "test" },
miniflare: {
bindings: { MY_SECRET: "test-value" },
},
// application code — handle both binding types
const secret = typeof env.MY_SECRET === "string"
? env.MY_SECRET
: await env.MY_SECRET.get();
Related issues
Please provide any relevant error logs
Error: Secret "BETTER_AUTH_SECRET" not found
❯ getAuth src/lib/auth.ts:47:45
Which Cloudflare product(s) does this pertain to?
vitest-pool-workers
What versions & operating system are you using?
@cloudflare/vitest-pool-workers@0.12.20(latest, verified — also reproduced on 0.12.19)miniflare@4.20260301.1wrangler@4.71.0Describe the Bug
When a worker uses
secrets_store_secretsinwrangler.jsonc, vitest-pool-workers correctly reads the config and creates the service bindings (with.get()), but the backing secrets store is always empty. Callingenv.SECRET.get()throwsError: Secret "..." not found.Root cause:
secretsStorePersistis a shared Miniflare option, but vitest-pool-workers only passes a fixed set of shared options:secretsStorePersistis not included. Even when specified in the vitest config'sminiflareblock, it's parsed as a per-worker option and silently ignored. Without it, Miniflare falls back to a fresh temporary directory, so the backing KV is always empty.This is different from
d1Persist,kvPersist,r2Persist, etc., which also aren't inSHARED_MINIFLARE_OPTIONS— but those are typically seeded in test setup (e.g.,applyD1Migrations). There's no equivalent API to seed the secrets store from within a test.Expected behavior
Either:
secretsStorePersistshould be forwarded to the Miniflare constructor (like other persist options), ORcloudflare:testAPI to seed secrets store values (analogous toapplyD1Migrations), ORWorkaround
Use a wrangler environment that omits
secrets_store_secrets, provide the secret as a plain string binding viaminiflare.bindings, and handle both types in application code:Related issues
@cloudflare/vite-plugintypeofpattern)Please provide any relevant error logs