mastra-ai/mastra · error · Error

Extractor name "${name}" produced invalid slug "${slug}".

Error message

Extractor name "${name}" produced invalid slug "${slug}".

What it means

After slugification, assertValidSlug enforces that the slug starts with a lowercase letter, ends with a letter or digit, and contains only lowercase letters, digits, and hyphens. A slug violating any of these rules throws this error naming both the source extractor name and the resulting slug.

Source

Thrown at packages/memory/src/processors/observational-memory/extractor.ts:120

  }

  return normalized.endsWith('-') ? normalized.slice(0, -1) : normalized;
}

function assertValidSlug(slug: string, name: string): void {
  if (!slug) {
    throw new Error(`Extractor name "${name}" must produce a non-empty slug.`);
  }
  const first = slug.charCodeAt(0);
  const last = slug.charCodeAt(slug.length - 1);
  const startsWithLetter = first >= 97 && first <= 122;
  const endsWithLetterOrNumber = (last >= 97 && last <= 122) || (last >= 48 && last <= 57);
  const hasOnlySlugCharacters = [...slug].every(char => {
    const code = char.charCodeAt(0);
    return (code >= 97 && code <= 122) || (code >= 48 && code <= 57) || char === '-';
  });
  if (!startsWithLetter || !endsWithLetterOrNumber || !hasOnlySlugCharacters) {
    throw new Error(`Extractor name "${name}" produced invalid slug "${slug}".`);
  }
}

export class Extractor<T = unknown> {
  readonly name: string;
  readonly slug: string;
  readonly instructions: string;
  readonly schema: z.ZodType<T>;
  readonly mode: ExtractorMode;
  readonly includePreviousExtraction: boolean;
  readonly metadataKeyPath: string | false;
  readonly onExtracted?: ExtractorConfig<T>['onExtracted'];
  readonly retryStructuredExtractionOnEmptyObject: boolean;
  /** @internal */
  readonly internal: boolean;
  private readonly instructionsConfig: ExtractorConfigValue<string>;
  private readonly schemaConfig?: ExtractorConfigValue<z.ZodType<T> | undefined>;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Rename the extractor so its slug starts with a letter and ends with a letter/digit (e.g. 'third-party-flags' instead of '3rd-party-flags')
  2. Prefix numeric or symbol-leading names with a word ('extractor-3rd-party')
  3. Pre-validate names with a regex like /^[a-z][a-z0-9-]*[a-z0-9]$/ before constructing extractors

Example fix

// before
new Extractor({ name: '3rd-party-flags', instructions: '...' });

// after
new Extractor({ name: 'third-party-flags', instructions: '...' });
Defensive patterns

Strategy: validation

Validate before calling

const SLUG_RE = /^[a-z][a-z0-9-]*[a-z0-9]$/;
if (!SLUG_RE.test(slugifyExtractorName(name))) {
  throw new Error(`Extractor name "${name}" must slugify to a valid slug`);
}

Try / catch

try {
  validateExtractorList(extractors);
} catch (err) {
  if (err instanceof Error && err.message.includes('produced invalid slug')) {
    console.error(err.message); // rename the offending extractor
  }
  throw err;
}

Prevention

When it happens

Trigger: Registering an Extractor whose name slugifies to something like "-foo-" (leading/trailing hyphen), "123abc" (starts with a digit), or containing invalid characters that survived normalization.

Common situations: Names starting with numbers (e.g. "3rd-party-flags"); names with underscores converted oddly; programmatically generated names built from enums or IDs that begin with digits; hyphen-only edges from names like "foo -".

Related errors


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