{"record":{"id":"33d6f9fd1f416d8d","repo":"mastra-ai/mastra","slug":"step-stepname-not-found-in-lesson-lessonna","errorCode":null,"errorMessage":"Step \"${stepName}\" not found in lesson \"${lessonName}\".","messagePattern":"Step \"(.+?)\" not found in lesson \"(.+?)\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp-docs-server/src/tools/course.ts","lineNumber":199,"sourceCode":"  return response.json() as Promise<{ success: boolean; id: string; key: string; message: string }>;\n}\n\nasync function readCourseStep(lessonName: string, stepName: string, _isFirstStep: boolean = false): Promise<string> {\n  // Find the lesson directory that matches the name\n  const lessonDirs = await fs.readdir(courseDir);\n  const lessonDir = lessonDirs.find(dir => dir.replace(/^\\d+-/, '') === lessonName);\n\n  if (!lessonDir) {\n    throw new Error(`Lesson \"${lessonName}\" not found.`);\n  }\n\n  // Find the step file that matches the name\n  const lessonPath = path.join(courseDir, lessonDir);\n  const files = await fs.readdir(lessonPath);\n  const stepFile = files.find(f => f.endsWith('.md') && f.replace(/^\\d+-/, '').replace('.md', '') === stepName);\n\n  if (!stepFile) {\n    throw new Error(`Step \"${stepName}\" not found in lesson \"${lessonName}\".`);\n  }\n\n  const filePath = path.join(courseDir, lessonDir, stepFile);\n\n  try {\n    const content = await fs.readFile(filePath, 'utf-8');\n    return wrapContentInPrompt(content);\n  } catch (error) {\n    throw new Error(`Failed to read step \"${stepName}\" in lesson \"${lessonName}\": ${error}`);\n  }\n}\n\n// Create a function to update course state on the local server\nexport function updateCourseStateOnServerLocally(deviceId: string, state: CourseState): Promise<void> {\n  return new Promise(async (resolve, reject) => {\n    try {\n      const creds = await getDeviceCredentials();\n      if (!creds) {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp-docs-server/src/tools/course.ts#L181-L217","documentation":"After locating the lesson directory, readCourseStep looks for a `.md` file whose name (with numeric prefix and `.md` extension stripped) equals stepName. If no file matches, it throws this error: the step does not exist inside the given lesson.","triggerScenarios":"Calling stepContent with a valid lessonName but a stepName that matches no markdown file in that lesson directory — typo, wrong step slug, or step renamed/removed in a newer course version.","commonSituations":"Agents guessing step names like 'introduction' when the file is 'overview'; users including the `.md` extension in stepName (the code strips it, so 'overview.md' will NOT match 'overview'); outdated course content caches.","solutions":["List the lesson directory's files and use the exact slug (numeric prefix and `.md` stripped), e.g. `overview` for `02-overview.md`.","Remove any `.md` extension from stepName before calling.","Fix typos and casing to match the step file name exactly."],"exampleFix":"// before\nawait stepContent({ lessonName: 'getting-started', stepName: 'overview.md' });\n// after\nawait stepContent({ lessonName: 'getting-started', stepName: 'overview' });","handlingStrategy":"validation","validationCode":"import { readdirSync } from 'node:fs';\nimport path from 'node:path';\nconst lessonDir = readdirSync(courseDir).find(d => d.replace(/^\\d+-/, '') === lessonName);\nconst steps = lessonDir\n  ? readdirSync(path.join(courseDir, lessonDir)).filter(f => f.endsWith('.md')).map(f => f.replace(/^\\d+-/, '').replace('.md', ''))\n  : [];\nif (!steps.includes(stepName)) {\n  throw new Error(`Invalid stepName \"${stepName}\". Available in \"${lessonName}\": ${steps.join(', ')}`);\n}\nawait stepContent({ lessonName, stepName });","typeGuard":null,"tryCatchPattern":"try {\n  const content = await stepContent({ lessonName, stepName });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not found in lesson')) {\n    // surface the valid step names instead of the raw error\n  } else throw e;\n}","preventionTips":["Never include the `.md` extension in stepName.","List the lesson's step slugs first and select from them.","Refresh step lists after any course content update."],"tags":["not-found","filesystem","input-validation"],"backgroundTag":"resource-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}