mastra-ai/mastra · error · WorkItemRelationError
Related work item not found in this project.
Error message
Related work item not found in this project.
What it means
validateParentRelation checks that any parent (related) work item passed to create/update actually exists within the same project. If parentWorkItemId does not match any item in the project's item list, WorkItemRelationError is thrown so no dangling cross-project or nonexistent relation is stored.
Source
Thrown at mastracode/factory/src/storage/domains/work-items/base.ts:598
}
function priorState(row: WorkItemDbRow): WorkItemPriorState {
return { stages: row.stages, sessionRoles: Object.keys(row.sessions) };
}
export class WorkItemRelationError extends Error {
readonly code = 'invalid_work_item_relation';
}
export function validateParentRelation(
projectItems: WorkItemRow[],
itemId: string | undefined,
parentWorkItemId: string | null,
): void {
if (parentWorkItemId === null) return;
const byId = new Map(projectItems.map(item => [item.id, item]));
const parent = byId.get(parentWorkItemId);
if (!parent) throw new WorkItemRelationError('Related work item not found in this project.');
if (itemId === parentWorkItemId) throw new WorkItemRelationError('A work item cannot relate to itself.');
const visited = new Set<string>();
let cursor: WorkItemRow | undefined = parent;
while (cursor?.parentWorkItemId) {
if (cursor.parentWorkItemId === itemId) {
throw new WorkItemRelationError('This relationship would create a cycle.');
}
if (visited.has(cursor.id)) throw new WorkItemRelationError('The related work item chain contains a cycle.');
visited.add(cursor.id);
cursor = byId.get(cursor.parentWorkItemId);
}
}
/**
* Diff `oldStages` → `newStages` and return the updated history: exited stages
* get `exitedAt` + `exitedBy` stamped on their open entry, entered stages get
* a new entry.View on GitHub (pinned to 75dd419e61)
Solutions
- Fetch the parent item first within the same project and confirm it exists before linking
- Verify the parentWorkItemId belongs to the same projectId as the child
- Handle WorkItemRelationError in the caller and surface a user-facing 'parent not found' message
- Re-query the project's work items if the parent was recently created (stale cache)
Example fix
// before
await workItems.update({ id: childId, parentWorkItemId: 'item-999' });
// after
const parent = await workItems.get({ projectId, id: 'item-999' });
if (!parent) throw new Error('Parent item not found in this project');
await workItems.update({ id: childId, parentWorkItemId: 'item-999' }); Defensive patterns
Strategy: validation
Validate before calling
const parent = projectItems.find(i => i.id === parentWorkItemId);
if (!parent) throw new Error(`Parent ${parentWorkItemId} not found in project ${projectId}`); Type guard
null
Try / catch
try {
await workItems.update({ id, parentWorkItemId });
} catch (e) {
if (e instanceof WorkItemRelationError && e.message.includes('not found in this project')) {
// surface 'parent not found' to user / pick a valid parent
} else throw e;
} Prevention
- Resolve parent IDs through the same project scope they will be linked in
- Re-fetch recent items before linking instead of trusting stale IDs
- Clean up child links when deleting parent items
When it happens
Trigger: Calling workItems create/update/#upsert with a parentWorkItemId that references a work item from another project, a deleted item, or a typo'd/nonexistent ID.
Common situations: Copy-pasting item IDs across projects, a parent item deleted before the child update is applied, or IDs coming from a different tenant/org context.
Related errors
- A work item cannot relate to itself.
- [FilesystemStorage] resourceId must not be empty.
- This relationship would create a cycle.
- The related work item chain contains a cycle.
- EXPERIMENT_RESULT_MISSING_EXPERIMENT_ID
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b83083b2cda01d24.
Report an issue: GitHub.