mastra-ai/mastra · error · Error
Item ${args.id} does not belong to dataset ${args.datasetId}
Error message
Item ${args.id} does not belong to dataset ${args.datasetId} What it means
InMemory _doUpdateItem() verifies that the live item row's datasetId equals args.datasetId and throws this plain Error when the item belongs to a different dataset. This guards against moving or editing an item under the wrong parent dataset when the caller supplies mismatched ids.
Source
Thrown at packages/core/src/storage/domains/datasets/inmemory.ts:287
// T3.11 — every mutation inserts exactly one dataset_version row
await this.createDatasetVersion(args.datasetId, newVersion);
return toDatasetItem(row);
}
protected async _doUpdateItem(args: UpdateDatasetItemInput): Promise<DatasetItem> {
const rows = this.db.datasetItems.get(args.id);
if (!rows || rows.length === 0) {
throw new Error(`Item not found: ${args.id}`);
}
const currentRow = rows.find(r => r.validTo === null && !r.isDeleted);
if (!currentRow) {
throw new Error(`Item not found: ${args.id}`);
}
if (currentRow.datasetId !== args.datasetId) {
throw new Error(`Item ${args.id} does not belong to dataset ${args.datasetId}`);
}
const dataset = this.db.datasets.get(args.datasetId);
if (!dataset) {
throw new Error(`Dataset not found: ${args.datasetId}`);
}
// Bump version (T3.26)
const newVersion = dataset.version + 1;
this.db.datasets.set(args.datasetId, { ...dataset, version: newVersion });
// T3.8 — close old row
currentRow.validTo = newVersion;
// T3.8 — insert new row with same id
const now = new Date();
const newRow: DatasetItemRow = {
id: args.id,View on GitHub (pinned to 75dd419e61)
Solutions
- Derive datasetId from the item itself (getItemById({id}).datasetId) instead of hardcoding it.
- Fix the mapping in your update script so each item is paired with its actual parent dataset.
- If the item truly must belong to another dataset, delete it there and re-insert it into the target dataset.
- Log both ids in the message when debugging — the error names both the item and the dataset.
Example fix
// before
await storage.datasets.updateItem({ id: itemId, datasetId: 'ds-a', groundTruth });
// after
const item = await storage.datasets.getItemById({ id: itemId });
await storage.datasets.updateItem({ id: itemId, datasetId: item.datasetId, groundTruth }); Defensive patterns
Strategy: type-guard
Validate before calling
const item = await storage.datasets.getItemById({ id: itemId });
if (item && item.datasetId !== datasetId) throw new Error(`Item '${itemId}' belongs to '${item.datasetId}', not '${datasetId}'`); Type guard
function belongsToDataset(item: { datasetId: string }, datasetId: string): boolean {
return item.datasetId === datasetId;
} Try / catch
try {
await storage.datasets.updateItem({ id: itemId, datasetId, input });
} catch (e) {
if (e instanceof Error && /does not belong to dataset/.test(e.message)) {
// fix the item->dataset pairing in the caller before retrying
} else throw e;
} Prevention
- Derive datasetId from the fetched item rather than hardcoding it in loops/config.
- Never assume item ids are globally reusable across datasets.
- In bulk scripts, group operations per item.datasetId.
When it happens
Trigger: updateItem({id, datasetId}) where the item id exists (live row) but was created in a dataset other than the datasetId passed — e.g., ids swapped in config, an item id reused across datasets, or a copy/paste mixing dataset ids.
Common situations: Bulk update scripts iterating items while hardcoding one datasetId, test fixtures where item ids collide across datasets, or callers passing the wrong relationship (item of dataset A updated with dataset B's id).
Related errors
- Dataset not found: ${args.id}
- Dataset not found: ${args.datasetId}
- Item not found: ${args.id}
- DATASETS_STORAGE_NOT_CONFIGURED
- DATASETS_STORE_NOT_AVAILABLE
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/0347c7e2b2f6896a.
Report an issue: GitHub.