Commit d8692af
fix(core): delegate MastraCompositeStore.init() to default and editor parents (#16786)
Fixes #16782.
When you give `MastraCompositeStore` a `default` (or `editor`) store, it
pulls out the inner domain instances and initializes them in parallel —
but never actually calls the parent's own `init()`. So any connection
setup, migrations, DDL ordering, or coalescing the parent adapter does
is silently skipped.
The loudest version of this is `LibSQLStore` on a local file: its
`init()` is where pragmas like `busy_timeout` and `journal_mode=WAL` get
applied and where domains init sequentially. Without it, the 17 parallel
`CREATE TABLE IF NOT EXISTS` statements race on the same SQLite file,
hit `SQLITE_BUSY`, and leave tables like `mastra_schedules` partially
created — then the scheduler trips with `no such table`. Other adapters
were quietly broken in the same way whenever their `init()` did real
work.
Before:
```ts
async init(): Promise<void> {
// domains init in parallel; default.init() / editor.init() never run
await Promise.all(Object.values(this.stores).map(d => d?.init()));
}
```
After:
```ts
async init(): Promise<void> {
// parents own their init contract — call it first
await Promise.all([this.parentDefault?.init(), this.parentEditor?.init()]);
// then only init domains not already covered by a parent
await Promise.all(orphanDomains.map(d => d.init()));
}
```
Subclasses that override `init()` (including `LibSQLStore` itself)
aren't affected.
Test plan: new `packages/core/src/storage/base.test.ts` covers default
delegation, editor delegation, both-at-once, and parent-init-failure
propagation. Existing storage + scheduler-integration + evented-workflow
tests all pass; `tsc --noEmit` clean.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## ELI5 (Explain Like I'm 5)
The PR makes sure the main supervisor (parent store) sets up the
database first so the workers (domain stores) don't try to create the
same tables at once and break things. This prevents races that caused
missing-table errors.
---
## Problem
MastraCompositeStore.init() used to initialize each domain store
directly and in parallel, but when parent stores (default or editor)
were supplied it did not call their init(). That skipped parent-level
setup (connection setup, pragmas, migrations, DDL ordering, and init
coalescing). On LibSQL local files this led to pragmas not being applied
and parallel CREATE TABLE statements racing (SQLITE_BUSY), leaving
tables partially created and causing runtime "no such table" errors
(e.g., mastra_schedules).
---
## Solution
- MastraCompositeStore now stores references to the provided parent
default and editor stores and delegates initialization to them first.
- init() calls parentDefault?.init() and parentEditor?.init() before
initializing domains.
- After parent init, only orphan domain instances (not already covered
by a parent) are initialized.
- Identical parent instances passed to multiple slots are deduped
(initialized exactly once).
- Existing init guards and subclass overrides (e.g., LibSQLStore) remain
unaffected; failures from parent init propagate through
composite.init().
---
## Changes
1. .changeset/gentle-garlics-clean.md — changelog entry describing the
fix.
2. packages/core/src/storage/base.ts — MastraCompositeStore:
- added protected parentDefault? and parentEditor? fields,
- refactored init to delegate to parents first, dedupe shared parent
instances, and only init remaining domain stores.
3. packages/core/src/storage/base.test.ts — new Vitest regression tests:
- verifies delegation to default and editor parents,
- verifies shared-parent dedupe (initialized once),
- verifies parent-init failure propagates through composite.init().
---
## Impact
- Fixes scheduler/startup races where WorkflowScheduler could see
uninitialized domain tables.
- Prevents parallel per-domain CREATE TABLE races on the same SQLite
file and associated SQLITE_BUSY / missing-table errors.
- Preserves adapter-specific init behavior and sequential/coalescing
semantics for parent stores.
- Existing storage, scheduler-integration, and evented-workflow tests
pass; TypeScript compiles clean.
---
Fixes `#16782`
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/mastra-ai/mastra/pull/16786?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Mastra Code (anthropic/claude-opus-4-7) <noreply@mastra.ai>1 parent c960279 commit d8692af
3 files changed
Lines changed: 199 additions & 74 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
237 | 237 | | |
238 | 238 | | |
239 | 239 | | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
240 | 250 | | |
241 | 251 | | |
242 | 252 | | |
| |||
258 | 268 | | |
259 | 269 | | |
260 | 270 | | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
261 | 276 | | |
262 | 277 | | |
263 | 278 | | |
| |||
323 | 338 | | |
324 | 339 | | |
325 | 340 | | |
326 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
327 | 354 | | |
328 | 355 | | |
329 | 356 | | |
330 | 357 | | |
331 | 358 | | |
332 | 359 | | |
333 | 360 | | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
352 | | - | |
353 | | - | |
354 | | - | |
355 | | - | |
356 | | - | |
357 | | - | |
358 | | - | |
359 | | - | |
360 | | - | |
361 | | - | |
362 | | - | |
363 | | - | |
364 | | - | |
365 | | - | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
376 | | - | |
377 | | - | |
378 | | - | |
379 | | - | |
380 | | - | |
381 | | - | |
382 | | - | |
383 | | - | |
384 | | - | |
385 | | - | |
386 | | - | |
387 | | - | |
388 | | - | |
389 | | - | |
390 | | - | |
391 | | - | |
392 | | - | |
393 | | - | |
394 | | - | |
395 | | - | |
396 | | - | |
397 | | - | |
398 | | - | |
399 | | - | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
400 | 364 | | |
401 | | - | |
402 | | - | |
403 | | - | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
404 | 385 | | |
405 | | - | |
406 | | - | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
407 | 415 | | |
408 | 416 | | |
409 | | - | |
410 | | - | |
| 417 | + | |
| 418 | + | |
411 | 419 | | |
412 | 420 | | |
413 | 421 | | |
| |||
0 commit comments