{"record":{"id":"2a5624525d3e2cee","repo":"mastra-ai/mastra","slug":"missing-required-query-param-label","errorCode":null,"errorMessage":"Missing required query param: ${label}","messagePattern":"Missing required query param: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/routes/fs.ts","lineNumber":216,"sourceCode":"\n/**\n * Resolve a path's real location (following symlinks) and confirm it stays\n * within `root`. Returns the real path when confined, or `null` when it escapes\n * the root or does not exist. Used so a symlink inside the root that points\n * outside it cannot be browsed or selected.\n */\nasync function realPathWithinRoot(candidate: string, root: string): Promise<string | null> {\n  try {\n    const real = await realpath(candidate);\n    return isWithinRoot(real, root) ? real : null;\n  } catch {\n    return null;\n  }\n}\n\nfunction assertRelativePath(path: string, label: string): string {\n  const trimmed = path.trim();\n  if (!trimmed) throw new Error(`Missing required query param: ${label}`);\n  if (isAbsolute(trimmed)) throw new Error(`${label} must be relative`);\n  if (trimmed.split(/[\\\\/]+/).includes('..')) throw new Error(`${label} escapes workspace`);\n  const normalized = resolve('/', trimmed).slice(1);\n  if (!normalized || normalized === '..' || normalized.startsWith(`..${sep}`))\n    throw new Error(`${label} escapes workspace`);\n  return normalized;\n}\n\nfunction assertApprovedRenderedRoot(renderedRoot: string): string {\n  const safeRoot = assertRelativePath(renderedRoot, 'root');\n  if (!APPROVED_RENDERED_ROOTS.has(safeRoot)) throw new Error('Root is not approved for rendered workspace access');\n  return safeRoot;\n}\n\nasync function confinedWorkspacePath(\n  root: string,\n  workspacePath: string,\n): Promise<{ resolvedRoot: string; workspace: string }> {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/routes/fs.ts#L198-L234","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Append the required query parameter, e.g. `GET /api/fs/read?path=src/index.ts`.","Check the error's label text and make sure the client sends a param with exactly that name.","Ensure empty-string values are either rejected client-side or defaulted to '.'/workspace root before the request.","Verify middleware/proxies are not stripping the query string."],"exampleFix":"// before\nawait fetch(`/api/fs/read`); // missing ?path\n// after\nawait fetch(`/api/fs/read?path=${encodeURIComponent(relativePath)}`);","handlingStrategy":"validation","validationCode":"function buildFsUrl(route: string, label: string, value: string | undefined): string {\n  if (!value || !value.trim()) throw new Error(`${label} is required before calling ${route}`);\n  return `${route}?${label}=${encodeURIComponent(value)}`;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await api.fsRead({ path });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Missing required query param')) {\n    console.error('Client bug: a required fs query param was empty/absent.', err.message);\n  }\n  throw err;\n}","preventionTips":["Reject empty path inputs at the UI/form layer before issuing requests.","Always send query params explicitly with encodeURIComponent; never build URLs by string concatenation with optional segments.","Check wrapper/fetch libraries for 'drop empty params' behavior."],"tags":["http","validation","query-params","filesystem"],"backgroundTag":"missing-query-param","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}