mastra-ai/mastra · error · Error
Item ${id} does not belong to dataset ${datasetId}
Error message
Item ${id} does not belong to dataset ${datasetId} What it means
Thrown by the in-memory dataset store when deleting an item whose current (live) SCD-2 row belongs to a different dataset than the one passed in. It means the item id exists but is not a member of the target datasetId, so the delete is refused to prevent cross-dataset mutation.
Source
Thrown at packages/core/src/storage/domains/datasets/inmemory.ts:347
// T3.11
await this.createDatasetVersion(args.datasetId, newVersion);
return toDatasetItem(newRow);
}
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 datasetsView on GitHub (pinned to 75dd419e61)
Solutions
- Verify the item's datasetId (getItem) and pass the dataset the item actually belongs to.
- Check you haven't swapped datasetId and id in the call arguments.
- If the item was re-created elsewhere, delete using the id returned by the create/batchInsert call in that dataset.
- If the item is already deleted, note deleteItem silently no-ops instead of throwing; only ownership mismatch throws.
Example fix
// before
await storage.datasets.deleteItem({ datasetId: 'ds-b', id: itemId });
// after
const item = await storage.datasets.getItem({ datasetId: 'ds-a', id: itemId });
await storage.datasets.deleteItem({ datasetId: item.datasetId, id: itemId }); Defensive patterns
Strategy: validation
Validate before calling
const item = await storage.datasets.getItem({ datasetId, id });
if (!item) throw new Error(`Item ${id} not found in dataset ${datasetId}`); Type guard
function belongsToDataset(item: { datasetId: string } | null, datasetId: string): item is { datasetId: string } {
return item !== null && item.datasetId === datasetId;
} Try / catch
try {
await storage.datasets.deleteItem({ datasetId, id });
} catch (e) {
if (String(e).includes('does not belong to dataset')) {
// wrong dataset — resolve the owning dataset and retry
} else throw e;
} Prevention
- Always carry datasetId together with item id in the same record.
- Resolve the owning dataset via getItem before cross-dataset operations.
- Avoid hardcoding dataset ids in scripts.
When it happens
Trigger: Calling storage.datasets.deleteItem({ datasetId, id }) with a valid item id that was created in a different dataset; passing a swapped datasetId/id pair; reusing a stale item reference after the item was moved or re-created in another dataset.
Common situations: Copy-paste of ids across datasets in tests or scripts; iterating a mixed list of item ids against one datasetId; client cache holding items from a previous dataset version.
Related errors
- Dataset not found: ${datasetId}
- Dataset not found: ${input.datasetId}
- Dataset item identity history is corrupt for externalId: ${f
- Experiment result ${input.id} does not belong to experiment
- DATASETS_STORAGE_NOT_CONFIGURED
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/09f49165b35395f9.
Report an issue: GitHub.