mastra-ai/mastra · error · Error
${name}: id must be provided and cannot be empty.
Error message
${name}: id must be provided and cannot be empty. What it means
MastraCompositeStore requires a non-empty string `id` in its config. The constructor validates it immediately and throws if it is missing, not a string, or whitespace-only. This guarantees every composite store has a stable identifier.
Source
Thrown at packages/core/src/storage/base.ts:375
* `prune()`. Undefined means nothing is pruned (keep forever).
*/
protected retention?: RetentionConfig;
/**
* Retained references to the parent stores supplied via composition. `init()`
* delegates to these so the parent's own `init()` logic (pragmas, ordered
* DDL, init coalescing, etc.) runs instead of being bypassed by the
* composite iterating the inner domains in parallel — which was the cause
* of the SQLITE_BUSY / "no such table" races reported in issue #16782.
*/
protected parentDefault?: MastraCompositeStore;
protected parentEditor?: MastraCompositeStore;
constructor(config: MastraCompositeStoreConfig) {
const name = config.name ?? 'MastraCompositeStore';
if (!config.id || typeof config.id !== 'string' || config.id.trim() === '') {
throw new Error(`${name}: id must be provided and cannot be empty.`);
}
super({
component: 'STORAGE',
name,
});
this.id = config.id;
this.disableInit = config.disableInit ?? false;
this.retention = config.retention;
// If composition config is provided (default, editor, or domains), compose the stores
if (config.default || config.editor || config.domains) {
const defaultStores = config.default?.stores;
const editorStores = config.editor?.stores;
const domainOverrides = config.domains ?? {};
// Retain the parent store refs so init() can delegate to their ownView on GitHub (pinned to 75dd419e61)
Solutions
- Pass a non-empty string `id` in the MastraCompositeStore config
- If the ID comes from user input or env, trim it and check truthiness before constructing
- Check for property-name typos (e.g. `Id`, `key`) so the real `id` field isn't left undefined
Example fix
// before
new MastraCompositeStore({ name: 'MyStore' });
// after
new MastraCompositeStore({ name: 'MyStore', id: 'my-store' }); Defensive patterns
Strategy: validation
Validate before calling
function assertValidStoreId(id: unknown): asserts id is string {
if (typeof id !== 'string' || id.trim() === '') {
throw new Error('MastraCompositeStore id must be a non-empty string');
}
}
assertValidStoreId(config.id); Type guard
function hasStoreId(config: { id?: unknown }): config is { id: string } {
return typeof config.id === 'string' && config.id.trim() !== '';
} Try / catch
try {
const store = new MastraCompositeStore(config);
} catch (e) {
if (e instanceof Error && e.message.includes('id must be provided')) {
throw new Error(`Invalid store config: ${config.name ?? 'unnamed'} is missing a non-empty id`);
}
throw e;
} Prevention
- Always set a unique, non-empty string id in composite store configs
- Trim user/env-supplied IDs before passing them in
- Centralize store construction in one factory that validates config
- Type the config with a required `id: string` field so TypeScript catches omissions
When it happens
Trigger: Calling `new MastraCompositeStore({ name })` or any subclass constructor without `config.id`, passing `id: ''`, a non-string (number, undefined), or a string of only whitespace like `' '`.
Common situations: Migrating from older store configs where `id` was optional; building the config object dynamically and leaving `id` unset; trimming user-supplied IDs that turn out to be empty; typos like `Id` vs `id`.
Related errors
- Factory storage domain name must not be empty
- Invalid retention duration: "${duration}". Expected a number
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
- MastraAuthBetterAuth needs a database to build its own bette
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/bceb6377cd8d8b11.
Report an issue: GitHub.