{"record":{"id":"538aa941e788a74e","repo":"withastro/astro","slug":"nomatchingimport-538aa9","errorCode":"NoMatchingImport","errorMessage":"Could not render `${componentName}`. No matching import has been found for `${componentName}`.","messagePattern":"Could not render `(.+?)`\\. No matching import has been found for `(.+?)`\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/integrations/mdx/src/rehype-analyze-astro-metadata.ts","lineNumber":49,"sourceCode":"\t\tconst imports = parseImports(tree.children);\n\n\t\tvisit(tree, (node) => {\n\t\t\tif (node.type !== 'mdxJsxFlowElement' && node.type !== 'mdxJsxTextElement') return;\n\n\t\t\tconst tagName = node.name;\n\t\t\tif (\n\t\t\t\t!tagName ||\n\t\t\t\t!isComponent(tagName) ||\n\t\t\t\t!(hasClientDirective(node) || hasServerDeferDirective(node))\n\t\t\t)\n\t\t\t\treturn;\n\n\t\t\t// From this point onwards, `node` is confirmed to be an island component\n\n\t\t\t// Match this component with its import source\n\t\t\tconst matchedImport = findMatchingImport(tagName, imports);\n\t\t\tif (!matchedImport) {\n\t\t\t\tthrow new AstroError(\n\t\t\t\t\tAstroErrorData.NoMatchingImport.message(node.name!),\n\t\t\t\t\tAstroErrorData.NoMatchingImport.hint,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If this is an Astro component, that means the `client:` directive is misused as it doesn't\n\t\t\t// work on Astro components as it's server-side only. Warn the user about this.\n\t\t\tif (matchedImport.path.endsWith('.astro')) {\n\t\t\t\tconst clientAttribute = node.attributes.find(\n\t\t\t\t\t(attr) => attr.type === 'mdxJsxAttribute' && attr.name.startsWith('client:'),\n\t\t\t\t) as MdxJsxAttribute | undefined;\n\t\t\t\tif (clientAttribute) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`You are attempting to render <${node.name!} ${\n\t\t\t\t\t\t\tclientAttribute.name\n\t\t\t\t\t\t} />, but ${node.name!} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.`,\n\t\t\t\t\t);\n\t\t\t\t}","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/integrations/mdx/src/rehype-analyze-astro-metadata.ts#L31-L67","documentation":"`rehype-analyze-astro-metadata` scans MDX for JSX elements that are components with a `client:` (or `server:defer`) directive — i.e. island candidates. It then matches the tag name against imports parsed from the file. If `findMatchingImport(tagName, imports)` returns nothing, it throws `AstroError` with `NoMatchingImport` so the user gets a clear, attributed build error.","triggerScenarios":"Using `<MyComp client:load />` in MDX without a corresponding `import MyComp from '...'`. Typo in the tag name vs the import. Component used via JSX member expression (`<UI.Button />`) that the importer cannot match. Import is dynamic/conditional and not statically visible.","commonSituations":"Forgot to import a component used with a hydration directive. Renamed an import but not the JSX usage. Mixing default vs named imports incorrectly. Component comes from a re-export the static parser doesn't follow.","solutions":["Add a static ESM `import` for the component used with `client:*` at the top of the `.mdx` file.","Verify the imported binding name exactly matches the JSX tag name.","If using a member expression, assign it to a capitalized local const and import that.","Remove the `client:` directive if the component is not meant to hydrate."],"exampleFix":"import Counter from '../components/Counter.astro';\n\n<Counter client:load />","handlingStrategy":"validation","validationCode":"function componentsWithClientDirectiveHaveImports(tree: any, imports: Map<string, Set<any>>) {\n  const missing: string[] = [];\n  visit(tree, (n: any) => {\n    if (n.type !== 'mdxJsxFlowElement' && n.type !== 'mdxJsxTextElement') return;\n    if (!n.name || !/^[A-Z]/.test(n.name)) return;\n    const hasClient = n.attributes?.some((a: any) => a.type === 'mdxJsxAttribute' && a.name.startsWith('client:'));\n    if (hasClient && !imports.has(n.name)) missing.push(n.name);\n  });\n  return missing;\n}","typeGuard":"function isImportedComponent(name: string, imports: Map<string, Set<unknown>>): boolean {\n  return imports.has(name);\n}","tryCatchPattern":null,"preventionTips":["Always import components used with `client:*` directives.","Match import binding names to JSX tag names exactly.","Lint MDX for client directives without imports."],"tags":["mdx","hydration","imports","build"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}