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

  1. Seed the request context with the controller before calling: `requestContext.set('controller', controller)` where the controller's state includes `projectPath`.
  2. Set `state.projectPath` (absolute path to the project root) on the `AgentControllerRequestContext<MastraCodeState>` state before any workspace/tool resolution runs.
  3. Only call `getDynamicWorkspace` (and dependent helpers) after controller initialization; defer workspace construction until the project path is known.
  4. In tests/scripts, construct a controller with `state = { projectPath: <abs path>, ... }` and put it in the RequestContext rather than passing an empty context.
  5. 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

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


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