mastra-ai/mastra · error
${this.name}: per-entity files directory is not configured
Error message
${this.name}: per-entity files directory is not configured What it means
A versioned filesystem domain computes per-entity snapshot file paths from a dedicated perEntityFilesDir; when that configuration field is unset, perEntityFilename() throws instead of writing files to an undefined location. It is a configuration guard, not a runtime failure of data operations.
Source
Thrown at packages/core/src/storage/filesystem-versioned.ts:162
* after the git history.
*/
private gitVersionCounts = new Map<string, number>();
constructor(config: FilesystemVersionedConfig) {
this.db = config.db;
this.entitiesFile = config.entitiesFile;
this.parentIdField = config.parentIdField;
this.name = config.name;
this.versionMetadataFields = config.versionMetadataFields;
this.gitHistoryLimit = config.gitHistoryLimit ?? 50;
this.perEntityFilesDir = config.perEntityFilesDir;
this.shouldPersistToPerEntityFile = config.shouldPersistToPerEntityFile;
this.perEntitySnapshotFilter = config.perEntitySnapshotFilter;
}
private perEntityFilename(entityId: string): string {
if (!this.perEntityFilesDir) {
throw new Error(`${this.name}: per-entity files directory is not configured`);
}
return getSourceControlEntityFilePath(this.perEntityFilesDir, entityId);
}
private entityIdFromPerEntityFilename(filename: string): string {
const basename = filename.split('/').pop() ?? filename;
return decodeURIComponent(basename.replace(/\.json$/, ''));
}
/**
* Check if a version ID represents a git-based version.
*/
static isGitVersion(id: string): boolean {
return id.startsWith(GIT_VERSION_PREFIX);
}
/**
* Hydrate in-memory state from the on-disk JSON file.View on GitHub (pinned to 75dd419e61)
Solutions
- Set `perEntityFilesDir` in the domain's config to a directory under the storage root.
- Only enable `shouldPersistToPerEntityFile: true` when perEntityFilesDir is provided.
- If per-entity files are not wanted, avoid the code path that calls filename()/persistToDisk per entity.
- Check the storage subclass's config wiring to ensure it passes the field through (see constructor assignment of this.perEntityFilesDir).
Example fix
// before
new MyVersionedDomain({ dir, shouldPersistToPerEntityFile: true }); // throws on persist
// after
new MyVersionedDomain({
dir,
shouldPersistToPerEntityFile: true,
perEntityFilesDir: path.join(dir, 'entities'),
}); Defensive patterns
Strategy: validation
Validate before calling
function assertPerEntityConfig(config) {
if (config.shouldPersistToPerEntityFile && !config.perEntityFilesDir) {
throw new Error('perEntityFilesDir is required when shouldPersistToPerEntityFile is true');
}
return config;
} Type guard
function hasPerEntityDir(cfg) {
return typeof cfg.perEntityFilesDir === 'string' && cfg.perEntityFilesDir.length > 0;
} Try / catch
try {
await domain.persistToDisk();
} catch (e) {
if (e.message.includes('per-entity files directory is not configured')) {
throw new Error(`${domain.name}: set perEntityFilesDir in the domain config to enable per-entity files.`);
}
throw e;
} Prevention
- Always provide perEntityFilesDir when enabling shouldPersistToPerEntityFile.
- Validate domain config at construction time (fail fast).
- Point perEntityFilesDir at a directory inside the storage root so traversal checks pass.
- Re-check config wiring when upgrading storage subclasses across versions.
When it happens
Trigger: Calling filename() or persistToDisk() on a versioned domain constructed without `perEntityFilesDir` in its config, while per-entity persistence (shouldPersistToPerEntityFile) is enabled/used.
Common situations: Custom storage subclass forgetting to set perEntityFilesDir in its config; enabling shouldPersistToPerEntityFile without supplying the directory; partial migration of config schemas between versions.
Related errors
- Configured domain path "${directory}" is a file, expected a
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
- MastraAuthBetterAuth needs a database to build its own bette
- [Slack] Failed to resolve Mastra storage. Ensure your Mastra
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/a932b3eff80c161e.
Report an issue: GitHub.