mastra-ai/mastra · error · Error
Lesson "${lessonName}" not found.
Error message
Lesson "${lessonName}" not found. What it means
readCourseStep resolves a lesson name to a directory under the course content dir by stripping the numeric prefix (e.g. `01-intro` -> `intro`). If no directory matches the given lessonName, it throws this error. It means the requested lesson does not exist in the bundled course content.
Source
Thrown at packages/mcp-docs-server/src/tools/course.ts:190
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
if (!response.ok) {
throw new Error(`Registration failed with status ${response.status}: ${response.statusText}`);
}
return response.json() as Promise<{ success: boolean; id: string; key: string; message: string }>;
}
async function readCourseStep(lessonName: string, stepName: string, _isFirstStep: boolean = false): Promise<string> {
// Find the lesson directory that matches the name
const lessonDirs = await fs.readdir(courseDir);
const lessonDir = lessonDirs.find(dir => dir.replace(/^\d+-/, '') === lessonName);
if (!lessonDir) {
throw new Error(`Lesson "${lessonName}" not found.`);
}
// Find the step file that matches the name
const lessonPath = path.join(courseDir, lessonDir);
const files = await fs.readdir(lessonPath);
const stepFile = files.find(f => f.endsWith('.md') && f.replace(/^\d+-/, '').replace('.md', '') === stepName);
if (!stepFile) {
throw new Error(`Step "${stepName}" not found in lesson "${lessonName}".`);
}
const filePath = path.join(courseDir, lessonDir, stepFile);
try {
const content = await fs.readFile(filePath, 'utf-8');
return wrapContentInPrompt(content);
} catch (error) {
throw new Error(`Failed to read step "${stepName}" in lesson "${lessonName}": ${error}`);View on GitHub (pinned to 75dd419e61)
Solutions
- List available lessons first (readdir of courseDir, stripping `^\d+-` prefixes) and use an exact slug match.
- Fix typos and match the case of the lesson directory name exactly.
- Check for a numeric-prefix mismatch: pass the name without the `01-` prefix, e.g. `intro` not `01-intro`.
Example fix
// before
await stepContent({ lessonName: 'Getting Started', stepName: 'overview' });
// after
await stepContent({ lessonName: 'getting-started', stepName: 'overview' }); Defensive patterns
Strategy: validation
Validate before calling
import { readdirSync } from 'node:fs';
const lessons = readdirSync(courseDir).map(d => d.replace(/^\d+-/, ''));
if (!lessons.includes(lessonName)) {
throw new Error(`Invalid lessonName "${lessonName}". Available: ${lessons.join(', ')}`);
}
await stepContent({ lessonName, stepName }); Try / catch
try {
const content = await stepContent({ lessonName, stepName });
} catch (e) {
if (e instanceof Error && e.message.includes('not found.')) {
// fall back to listing lessons for the user
} else throw e;
} Prevention
- Enumerate lesson slugs before calling and pick from that list, never freeform strings.
- Strip numeric prefixes mentally: pass 'intro', not '01-intro'.
- Log the available lessons in the error path to aid the caller.
When it happens
Trigger: Calling the course step tool (via stepContent) with a lessonName that does not match any directory in courseDir after prefix stripping — e.g. a typo, wrong casing, or asking for a lesson removed from the course.
Common situations: LLM agents hallucinating lesson names; users passing human-readable titles ('Getting Started') instead of slug names ('getting-started'); course content updated between versions so old lesson names no longer exist.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Step "${stepName}" not found in lesson "${lessonName}".
- Not found at ref ${ref}: ${path}
- Template "${slug}" not found. Available templates: ${templat
- ENOENT: no such file or directory: ${path}
- FilesystemSkillsStorage: skill with id ${id} not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/58bbaf23311cfcc6.
Report an issue: GitHub.