mastra-ai/mastra · error · HTTPException

Malformed referencePath

Error message

Malformed referencePath

What it means

The referencePath parameter may be URL-encoded, so the handler decodes it with decodeURIComponent. If decoding fails (invalid percent sequences such as a stray '%'), it throws a 400 'Malformed referencePath'.

Source

Thrown at packages/server/src/server/handlers/workspace.ts:1081

      if (!skills) {
        throw new HTTPException(404, { message: 'No workspace with skills configured' });
      }

      // Refresh skills with request context (handles dynamic skill resolvers)
      await skills.maybeRefresh({ requestContext });

      // Resolve skill to get its name for the response
      const skill = await skills.get(identifier);
      if (!skill) {
        throw new HTTPException(404, { message: `Skill "${identifier}" not found` });
      }

      // Decode the reference path (it may be URL encoded)
      let decodedPath: string;
      try {
        decodedPath = decodeURIComponent(referencePath);
      } catch {
        throw new HTTPException(400, { message: 'Malformed referencePath' });
      }

      // Prevent path traversal via the reference path parameter
      assertSafeFilePath(decodedPath);

      // getReference expects a path relative to skill.path, so prepend 'references/'
      // since the URL path already contains the literal /references/ segment
      const content = await skills.getReference(identifier, `references/${decodedPath}`);
      if (content === null) {
        throw new HTTPException(404, {
          message: `Reference "${decodedPath}" not found in skill "${identifier}"`,
        });
      }

      return {
        skillName: skill.name,
        referencePath: decodedPath,
        content,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. URL-encode the reference path on the client with encodeURIComponent before inserting it into the URL.
  2. Remove or escape stray '%' characters in the path (literal percent must be sent as %25).
  3. If double-encoding is suspected, send the path encoded exactly once.

Example fix

// before
const url = `/skills/my-skill/references/${path}` // path = 'a%b.md'
// after
const url = `/skills/my-skill/references/${encodeURIComponent(path)}`;
Defensive patterns

Strategy: validation

Validate before calling

let encoded: string;
try {
  encoded = encodeURIComponent(referencePath);
} catch {
  throw new Error('referencePath cannot be encoded');
}
if (/%(?![0-9A-Fa-f]{2})/.test(referencePath)) {
  throw new Error('referencePath contains a stray % — encode it as %25');
}

Type guard

function isPercentSafePath(p: string): boolean {
  return !/%(?![0-9A-Fa-f]{2})/.test(p);
}

Try / catch

try {
  return await client.getSkillReference({ skillName, referencePath });
} catch (e) {
  if (isHttpException(e, 400) && String(e.message).includes('Malformed')) {
    throw new Error('Fix client encoding: use encodeURIComponent exactly once');
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a referencePath containing an invalid percent-encoding sequence, e.g. `%ZZ` or a lone `%`, in the URL.

Common situations: Double-encoding bugs in client code; manually concatenating Windows paths with '%' characters into URLs; frameworks partially encoding the path so '%' survives unescaped.

Understand the failure class

Related errors


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