mastra-ai/mastra · error · Error
Dataset not found: ${datasetId}
Error message
Dataset not found: ${datasetId} What it means
Thrown after the ownership check when bumping the dataset version during deleteItem: the datasetId no longer resolves in the datasets map. The item row exists, but the parent dataset was deleted concurrently or never existed under that id.
Source
Thrown at packages/core/src/storage/domains/datasets/inmemory.ts:352
}
protected async _doDeleteItem({ id, datasetId }: DeleteDatasetItemInput): Promise<void> {
const rows = this.db.datasetItems.get(id);
if (!rows || rows.length === 0) {
return; // no-op if item doesn't exist
}
const currentRow = rows.find(r => r.validTo === null && !r.isDeleted);
if (!currentRow) {
return; // already deleted
}
if (currentRow.datasetId !== datasetId) {
throw new Error(`Item ${id} does not belong to dataset ${datasetId}`);
}
const dataset = this.db.datasets.get(datasetId);
if (!dataset) {
throw new Error(`Dataset not found: ${datasetId}`);
}
// Bump version (T3.26)
const newVersion = dataset.version + 1;
this.db.datasets.set(datasetId, { ...dataset, version: newVersion });
// T3.9 — close old row
currentRow.validTo = newVersion;
// T3.9 — insert tombstone.
// Tenancy is read from the prior current row rather than re-fetched from
// the parent dataset (the pattern used by every DB adapter). This is
// deliberate and safe: tenancy is immutable post-create on both datasets
// and items (see CreateDatasetInput / UpdateDatasetInput in ../../types.ts),
// so currentRow.organizationId / currentRow.projectId are guaranteed to
// equal dataset.organizationId / dataset.projectId. Keep this branch in
// sync with the DB adapters if that invariant ever changes.
const now = new Date();View on GitHub (pinned to 75dd419e61)
Solutions
- Confirm the dataset exists first: dataset.get(datasetId) before deleting items.
- Reorder logic to delete items before deleting the dataset, or rely on cascade deletion of items.
- Refresh dataset/item ids after store restart — in-memory data does not persist.
- Serialize concurrent dataset mutations or guard with existence checks in your workflow.
Example fix
// before
await storage.datasets.deleteItem({ datasetId, id });
// after
const ds = await storage.datasets.get(datasetId);
if (ds) await storage.datasets.deleteItem({ datasetId, id }); Defensive patterns
Strategy: validation
Validate before calling
const ds = await storage.datasets.get(datasetId); if (!ds) return; // dataset gone; skip item deletion
Type guard
null
Try / catch
try {
await storage.datasets.deleteItem({ datasetId, id });
} catch (e) {
if (String(e).startsWith('Dataset not found')) return; // idempotent cleanup
throw e;
} Prevention
- Delete items before deleting their dataset, or rely on cascade.
- Re-fetch ids after any store restart — in-memory storage is ephemeral.
- Guard concurrent dataset deletions with existence checks.
When it happens
Trigger: deleteItem({ datasetId, id }) where the dataset was deleted between item creation and the delete call; a typo'd datasetId that happens to match a stale item row; concurrent deletion of the dataset from another request in the same process.
Common situations: Test teardown deleting datasets while cleanup code still deletes items; in-memory store restarted (data lost) while the caller cached old ids; race between dataset deletion and item deletion in async code.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Dataset not found: ${input.datasetId}
- Item ${id} does not belong to dataset ${datasetId}
- Dataset item identity history is corrupt for externalId: ${f
- Experiment not found: ${input.id}
- Experiment result not found: ${input.id}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/40adf7073b11869e.
Report an issue: GitHub.