mastra-ai/mastra · error · MastraError
DATASET_NOT_FOUND
DATASET_NOT_FOUND
Error message
Dataset not found
What it means
manager.get looks up a dataset by id (scoped by optional organizationId/projectId filters) via store.getDatasetById and throws DATASET_NOT_FOUND when no record matches. Raised in get and its callers (finalizeExperiment, resultA, resultB) when the referenced dataset doesn't exist or isn't visible in the given scope.
Solutions
- Verify the dataset id exists (list datasets) and matches the organizationId/projectId you pass.
- Catch DATASET_NOT_FOUND and surface a user-facing 'dataset missing' message or trigger re-creation.
- Check scope: pass the same organizationId/projectId used at creation time.
- For finalize/result flows, guard dataset lifetime so datasets aren't deleted while experiments reference them.
Example fix
// before
const ds = await datasets.get({ id: datasetId, organizationId, projectId }); // throws if absent
// after
let ds;
try {
ds = await datasets.get({ id: datasetId, organizationId, projectId });
} catch (err) {
if (err?.id === 'DATASET_NOT_FOUND') {
ds = await datasets.create({ name: 'evals', organizationId, projectId });
} else throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
const existing = await datasets.list({ organizationId, projectId, /* name filter if available */ });
if (!existing.some(d => d.id === datasetId)) throw new Error(`Dataset ${datasetId} not found in scope`); Type guard
function isDatasetNotFound(e: unknown): e is { id: 'DATASET_NOT_FOUND'; text: string } {
return typeof e === 'object' && e !== null && (e as any).id === 'DATASET_NOT_FOUND';
} Try / catch
try {
return await datasets.get({ id, organizationId, projectId });
} catch (err) {
if (isDatasetNotFound(err)) return null; // or re-create / report to user
throw err;
} Prevention
- Pass the same organizationId/projectId scope used when the dataset was created.
- Look up dataset ids dynamically (by name) instead of hardcoding across environments.
- Prevent deleting datasets that active experiments reference (check finalizeExperiment flows).
- Handle DATASET_NOT_FOUND as a first-class state in multi-tenant UIs.
When it happens
Trigger: Fetching a dataset with a wrong/deleted id; id from another project/organization passed without matching scope filters; dataset removed between creating an experiment and finalizing it.
Common situations: Hardcoded dataset ids drifting across environments; multi-tenant apps where projectId scoping hides the dataset; race with dataset deletion; using an experiment's datasetId after the dataset was purged.
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
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3c6f74263ca662b8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/datasets/manager.ts:166
const createScope = scopeFromArgs(input);
return new Dataset(result.id, this.#mastra, createScope);
}
/**
* Get an existing dataset by ID, optionally scoped to a tenant.
*
* When `organizationId` / `projectId` are provided, the read is scoped to
* that tenancy: a dataset row that exists but belongs to a different tenant
* returns NOT_FOUND (same 404 as a truly missing row) rather than leaking
* cross-tenant existence. The returned {@link Dataset} handle carries the
* scope forward on all subsequent reads and item mutations.
*/
async get(args: { id: string; organizationId?: string; projectId?: string }): Promise<Dataset> {
const store = await this.#getDatasetsStore();
const scope = scopeFromArgs(args);
const record = await store.getDatasetById({ id: args.id, filters: scope });
if (!record) {
throw new MastraError({
id: 'DATASET_NOT_FOUND',
text: 'Dataset not found',
domain: 'STORAGE',
category: 'USER',
});
}
return new Dataset(args.id, this.#mastra, scope);
}
/**
* List all datasets with pagination.
*
* Supports optional tenancy and candidate-identity filters. When omitted, all
* datasets visible to the configured storage instance are returned.
*/
async list(args?: {
page?: number;
perPage?: number;View on GitHub (pinned to 75dd419e61)