mastra-ai/mastra · error

Missing required query param: ${label}

Error message

Missing required query param: ${label}

What it means

The filesystem route validates query params through `assertRelativePath`, which throws `Missing required query param: ${label}` when the parameter is absent or empty/whitespace after trimming. The label is the parameter name the caller must supply (e.g. 'path', 'root', 'previousPath'), so the message tells you exactly which query parameter is missing.

Source

Thrown at mastracode/factory/src/routes/fs.ts:216

/**
 * Resolve a path's real location (following symlinks) and confirm it stays
 * within `root`. Returns the real path when confined, or `null` when it escapes
 * the root or does not exist. Used so a symlink inside the root that points
 * outside it cannot be browsed or selected.
 */
async function realPathWithinRoot(candidate: string, root: string): Promise<string | null> {
  try {
    const real = await realpath(candidate);
    return isWithinRoot(real, root) ? real : null;
  } catch {
    return null;
  }
}

function assertRelativePath(path: string, label: string): string {
  const trimmed = path.trim();
  if (!trimmed) throw new Error(`Missing required query param: ${label}`);
  if (isAbsolute(trimmed)) throw new Error(`${label} must be relative`);
  if (trimmed.split(/[\\/]+/).includes('..')) throw new Error(`${label} escapes workspace`);
  const normalized = resolve('/', trimmed).slice(1);
  if (!normalized || normalized === '..' || normalized.startsWith(`..${sep}`))
    throw new Error(`${label} escapes workspace`);
  return normalized;
}

function assertApprovedRenderedRoot(renderedRoot: string): string {
  const safeRoot = assertRelativePath(renderedRoot, 'root');
  if (!APPROVED_RENDERED_ROOTS.has(safeRoot)) throw new Error('Root is not approved for rendered workspace access');
  return safeRoot;
}

async function confinedWorkspacePath(
  root: string,
  workspacePath: string,
): Promise<{ resolvedRoot: string; workspace: string }> {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Append the required query parameter, e.g. `GET /api/fs/read?path=src/index.ts`.
  2. Check the error's label text and make sure the client sends a param with exactly that name.
  3. Ensure empty-string values are either rejected client-side or defaulted to '.'/workspace root before the request.
  4. Verify middleware/proxies are not stripping the query string.

Example fix

// before
await fetch(`/api/fs/read`); // missing ?path
// after
await fetch(`/api/fs/read?path=${encodeURIComponent(relativePath)}`);
Defensive patterns

Strategy: validation

Validate before calling

function buildFsUrl(route: string, label: string, value: string | undefined): string {
  if (!value || !value.trim()) throw new Error(`${label} is required before calling ${route}`);
  return `${route}?${label}=${encodeURIComponent(value)}`;
}

Try / catch

try {
  return await api.fsRead({ path });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Missing required query param')) {
    console.error('Client bug: a required fs query param was empty/absent.', err.message);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a /fs route (via safeRoot, safeRelativePath, safePath, or safePreviousPath handlers) without the required query string parameter, e.g. `GET /api/fs/read` with no `?path=`, or `?path=` / `?path=%20%20` (empty or whitespace-only).

Common situations: Frontend code building the URL conditionally and dropping the param when the value is an empty string; form inputs left blank; fetch wrappers stripping empty params; missing URL encoding causing the param to be dropped by middleware.

Related errors


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