mastra-ai/mastra · critical
Project path is required
Error message
Project path is required
What it means
`getDynamicWorkspace` builds the agent's workspace (filesystem, sandbox, skills, tools) from the request context's controller state. It reads `state.projectPath` from the `controller` entry in the `RequestContext`; when the context or state is missing, or `projectPath` is empty/undefined, it throws because no workspace root can be resolved for the project.
Source
Thrown at mastracode/sdk/src/agents/workspace.ts:197
return 'npx --yes';
}
export async function getDynamicWorkspace({
requestContext,
mastra,
skillExtension,
}: {
requestContext: RequestContext;
mastra?: Mastra;
skillExtension?: WorkspaceSkillExtension;
}) {
const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;
const state = ctx?.getState();
const rawProjectPath = state?.projectPath;
if (!rawProjectPath) {
throw new Error('Project path is required');
}
const projectPath = path.resolve(rawProjectPath);
const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;
const projectSkillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);
const skillPaths = [...(skillExtension?.paths ?? []), ...projectSkillPaths];
const extensionId = skillExtension ? `-${skillExtension.id}` : '';
const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}${extensionId}`;
const sandboxPaths = state?.sandboxAllowedPaths ?? [];
const allowedPaths = [
...projectSkillPaths,
...DEFAULT_ALLOWED_PATHS,
...sandboxPaths.map((p: string) => path.resolve(p)),
];
// All modes share the same workspace tool configuration. Per-mode tool
// visibility is enforced at LLM-call time via `availableTools` /
// `activeTools` on the AgentController, not by mutating workspace capabilities.View on GitHub (pinned to 75dd419e61)
Solutions
- Seed the request context with the controller before calling: `requestContext.set('controller', controller)` where the controller's state includes `projectPath`.
- Set `state.projectPath` (absolute path to the project root) on the `AgentControllerRequestContext<MastraCodeState>` state before any workspace/tool resolution runs.
- Only call `getDynamicWorkspace` (and dependent helpers) after controller initialization; defer workspace construction until the project path is known.
- In tests/scripts, construct a controller with `state = { projectPath: <abs path>, ... }` and put it in the RequestContext rather than passing an empty context.
- Validate/normalize projectPath upstream and reject sessions without a project before agent execution starts.
Example fix
// before
const ws = await getDynamicWorkspace({ requestContext }); // controller never set -> throws
// after
requestContext.set('controller', controller); // controller.state.projectPath = '/abs/path/to/project'
const ws = await getDynamicWorkspace({ requestContext }); Defensive patterns
Strategy: validation
Validate before calling
const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;
if (!ctx?.getState()?.projectPath) {
throw new Error('cannot build workspace: controller state has no projectPath');
}
const ws = await getDynamicWorkspace({ requestContext }); Type guard
function hasProjectPath(ctx: unknown): ctx is AgentControllerRequestContext<MastraCodeState> & { getState(): MastraCodeState & { projectPath: string } } {
const c = ctx as AgentControllerRequestContext<MastraCodeState> | undefined;
return typeof c?.getState?.()?.projectPath === 'string' && c.getState().projectPath.length > 0;
} Try / catch
try {
const ws = await getDynamicWorkspace({ requestContext });
} catch (err) {
if (err instanceof Error && err.message === 'Project path is required') {
// fall back to a default/no-project workspace or prompt the user to open a project
} else {
throw err;
}
} Prevention
- Always set the 'controller' entry in RequestContext before agent/workspace code runs
- Initialize controller state with an absolute projectPath before tool resolution
- Gate workspace-dependent features until a project is selected/opened
- In headless scripts and tests, construct a controller with projectPath in state
- Validate projectPath non-empty when persisting/restoring MastraCodeState across versions
When it happens
Trigger: Calling `getDynamicWorkspace({ requestContext, ... })` where `requestContext.get('controller')` is undefined (no controller registered in the context), the controller has no state yet, or `state.projectPath` is an empty string. Callers include `workspace`, `buildWorkspaceWithLspSetting`, `getGoalJudgeTools`, and `controller` — any of these code paths hitting an uninitialized request context triggers it.
Common situations: Invoking agent code outside the normal TUI/server request lifecycle (scripts, tests, one-off tool runs) without seeding the request context; agent sessions started before project selection; `projectPath` omitted from persisted `MastraCodeState` after an upgrade or state migration; running `getGoalJudgeTools` in a headless evaluation harness.
Related errors
- Skill not found: ${invocation.skillName}.
- No model available: this run started without a controller se
- A session workspace must be a valid Workspace instance.
- MASTRA_ADD_WORKSPACE_MISSING_AGENT_METADATA
- CompositeFilesystem requires at least one mount
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/55043d8283766766.
Report an issue: GitHub.