mastra-ai/mastra · error · HTTPException

Item not found in dataset: ${itemId}

Error message

Item not found in dataset: ${itemId}

What it means

The LIST_ITEM_VERSIONS route (GET /datasets/:datasetId/items/:itemId/history) returns the SCD-2 history rows for an item. Because getItemHistory looks up rows by itemId globally, the handler verifies the first returned row's datasetId matches the path's datasetId; if it doesn't, the item exists but belongs to a different dataset, so a 404 is raised rather than leaking the item's existence in another dataset.

Source

Thrown at packages/server/src/server/handlers/datasets.ts:1135

export const LIST_ITEM_VERSIONS_ROUTE = createRoute({
  method: 'GET',
  path: '/datasets/:datasetId/items/:itemId/history',
  responseType: 'json',
  pathParamSchema: datasetAndItemIdPathParams,
  responseSchema: listItemVersionsResponseSchema,
  summary: 'Get item history',
  description: 'Returns the full SCD-2 history of the item across all dataset versions',
  tags: ['Datasets'],
  requiresAuth: true,
  handler: async ({ mastra, datasetId, itemId }) => {
    assertDatasetsAvailable();
    try {
      const ds = await mastra.datasets.get({ id: datasetId });
      const rows = await ds.getItemHistory({ itemId });
      // Check rows belong to this dataset
      if (rows.length > 0 && rows[0]?.datasetId !== datasetId) {
        throw new HTTPException(404, { message: `Item not found in dataset: ${itemId}` });
      }
      return { history: rows };
    } catch (error) {
      if (error instanceof MastraError) {
        throw new HTTPException(getHttpStatusForMastraError(error.id) as StatusCode, { message: error.message });
      }
      return handleError(error, 'Error listing item history');
    }
  },
});

export const GET_ITEM_VERSION_ROUTE = createRoute({
  method: 'GET',
  path: '/datasets/:datasetId/items/:itemId/versions/:datasetVersion',
  responseType: 'json',
  pathParamSchema: datasetItemVersionPathParams,
  responseSchema: datasetItemResponseSchema.nullable(),
  summary: 'Get item at specific dataset version',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the itemId actually belongs to the datasetId in the request path (list items via GET /datasets/:datasetId/items and cross-check).
  2. Fix a mixed-up datasetId/itemId pair in the client code or saved configuration.
  3. If the item was moved or the dataset recreated, use the new dataset's ID or re-add the item.
  4. Ensure you're pointing at the correct Mastra server/deployment (IDs may differ across environments).

Example fix

// before
await fetch(`/api/datasets/${wrongDatasetId}/items/${itemId}/history`);
// after
const items = await fetch(`/api/datasets/${datasetId}/items`).then(r => r.json());
if (!items.items.some(i => i.id === itemId)) throw new Error('item not in this dataset');
await fetch(`/api/datasets/${datasetId}/items/${itemId}/history`);
Defensive patterns

Strategy: try-catch

Validate before calling

const items = await fetch(`/api/datasets/${datasetId}/items?perPage=100`).then(r => r.json());
if (!items.items.some(i => i.id === itemId)) {
  throw new Error(`Item ${itemId} does not belong to dataset ${datasetId}`);
}

Type guard

function isItemInDataset(history: Array<{ datasetId: string }>, datasetId: string): boolean {
  return history.length === 0 || history[0]?.datasetId === datasetId;
}

Try / catch

try {
  const res = await fetch(`/api/datasets/${datasetId}/items/${itemId}/history`);
  if (res.status === 404) {
    console.warn(`Item ${itemId} not in dataset ${datasetId}; verify IDs`);
    return null;
  }
  if (!res.ok) throw new Error(await res.text());
  return await res.json();
} catch (err) {
  console.error('listItemVersions failed', err);
  throw err;
}

Prevention

When it happens

Trigger: Call GET /api/datasets/:datasetId/items/:itemId/history with an itemId that exists in some dataset but not the one named in the path. getItemHistory returns rows whose datasetId differs from the path datasetId.

Common situations: Copy-pasting an itemId from one dataset while calling against another datasetId in the URL; stale cached IDs after a dataset was re-created with a new ID; multi-tenant setups where two datasets contain items with the same itemId.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/815e69758c5e03c1. Report an issue: GitHub.