Errors and Troubleshooting

Purpose and Scope

Astro troubleshooting starts with separating three questions: where the error happened, which runtime produced the message, and what environment information is needed to reproduce it. Astro projects can fail during local development, static build or prerendering, server rendering, client hydration, or framework integration rendering. The official troubleshooting guidance emphasizes simple diagnostics first: frontmatter code and server-rendered framework components log to the terminal, while code inside an Astro script tag logs in the browser console. That distinction matters because Astro executes component frontmatter on the server even when the final page is delivered to the browser.

This page focuses on the repository-backed pieces that make Astro errors actionable: the public error exports, development-time Vite error helpers, build-time rendering behavior, and the debug information providers used by CLI support flows. The source code shows that Astro treats errors as typed runtime objects, exposes utilities for safe error handling, and formats environment details as a stable list of labeled values. Use this page when you need to decide whether to inspect terminal output, browser output, build logs, an Astro error reference entry, or a project environment report.

Sources: packages/astro/src/core/errors/index.ts, packages/astro/src/core/errors/dev/index.ts, packages/astro/src/core/errors/build-handler.ts, packages/astro/src/cli/info/domain/debug-info.ts, packages/astro/src/cli/info/infra/cli-debug-info-provider.ts, packages/astro/src/cli/info/infra/dev-debug-info-provider.ts

Relevant Source Files

  • packages/astro/src/core/errors/build-handler.ts defines the BuildErrorHandler used during static build and prerendering, including the special treatment for status 500 responses.
  • packages/astro/src/core/errors/dev/index.ts is the development error helper barrel that re-exports Vite SSR error enhancement and metadata collection utilities.
  • packages/astro/src/core/errors/index.ts is the public core error barrel for AstroError, AstroUserError, CompilerError, MarkdownError, CSSError, AggregateError, AstroErrorData, and helper utilities.
  • packages/astro/src/cli/info/domain/debug-info.ts defines the DebugInfo shape as an array of labeled string values or labeled string arrays.
  • packages/astro/src/cli/info/infra/cli-debug-info-provider.ts builds the full CLI debug report, including package versions for Vite, adapters, and integrations when available.
  • packages/astro/src/cli/info/infra/dev-debug-info-provider.ts builds a faster development-server debug report without package version lookups.

Troubleshooting Workflow

Start by locating the runtime boundary. Astro frontmatter and server-rendered framework components execute on the server, so console.log() there appears in the terminal running Astro. Code inside an Astro <script> tag executes in the browser, so browser DevTools is the right place to inspect it. Hydrated framework components can produce output in both places because they render on the server first and then run in the browser. When a value needs to be inspected in rendered HTML without adding browser JavaScript, the official docs recommend Astro’s built-in <Debug /> component from astro:components.

After identifying the runtime, match the symptom to the phase. Development errors often pass through Vite’s SSR pipeline, so Astro exposes dev helpers named enhanceViteSSRError, getViteErrorPayload, and collectErrorMetadata. Those names communicate the intended diagnostic path: enrich the raw Vite SSR exception, collect metadata that can be shown to the developer, and produce a payload suitable for the development error UI or client. When the same project fails only during astro build, switch attention to prerendering and static output behavior rather than assuming a browser-only bug.

Sources: packages/astro/src/core/errors/dev/index.ts, packages/astro/src/core/errors/build-handler.ts

Error System and Build Behavior

Astro’s core error entrypoint exports a small taxonomy of error classes and helpers rather than a single untyped exception. AstroError is the central framework error, AstroUserError represents user-facing configuration or usage problems, and specialized classes such as CompilerError, MarkdownError, and CSSError let the runtime preserve the source of a failure. The same barrel exports isAstroError for type checks, createSafeError for safer error construction, positionAt for location work, errorMap for Zod validation messages, and AstroErrorData for the catalog of framework error definitions.

Build-time error handling is intentionally different from production server rendering. BuildErrorHandler wraps DefaultErrorHandler, but its renderError(request, options) method treats status 500 as a build-stopping condition unless an original response already exists. If options.status is 500 and options.response is present, it returns that response; otherwise it throws options.error so the build surfaces the underlying problem. For non-500 statuses such as 404 handling, it delegates to the default handler while clearing prerenderedErrorPageFetch, because the static build pipeline cannot fetch prerendered pages the same way production SSR can.

Sources: packages/astro/src/core/errors/index.ts, packages/astro/src/core/errors/build-handler.ts

Debug Info Reference

Astro’s debug information model is deliberately simple: DebugInfo is Array<[string, string | Array<string>]>. Each entry is a label paired with either one string value or a list of string values. That shape is useful for support output because it can represent single facts such as Astro version, Node version, operating system, package manager, output mode, and adapter, while also representing plural values such as installed integrations. When reporting a problem, this is the environment snapshot that helps distinguish a framework regression from a project-specific adapter, integration, package manager, or runtime mismatch.

The full CLI provider, CliDebugInfoProvider, receives the Astro config subset output, adapter, and integrations, plus providers for Astro version, package manager, operating system, and Node version. Its get() method starts with Astro, Node, system, package manager, and output. It then looks up the installed Vite version and inserts it near the top when found. Adapter output is either the adapter name with its package version or none; integrations are listed with package versions when available, or reported as none when the project has no integrations.

The development provider, DevDebugInfoProvider, implements the same support concept but avoids package-version lookups to keep the dev server responsive. Its get() method returns Astro, Node, system, package manager, output, adapter name or none, and integration names or none. This tradeoff is important during active debugging: a fast in-process report is preferable while the server is running, while the CLI report can afford richer package inspection when preparing information for issue reports, support threads, or reproduction notes.

Sources: packages/astro/src/cli/info/domain/debug-info.ts, packages/astro/src/cli/info/infra/cli-debug-info-provider.ts, packages/astro/src/cli/info/infra/dev-debug-info-provider.ts

Practical Diagnosis Checklist

When an Astro project fails, first reproduce the smallest failing route or component and note whether the message appears in the terminal, browser console, build output, or server logs. Next, compare the error name against the official Error Reference. The reference includes framework-specific names such as NoAdapterInstalled, AdapterSupportOutputMismatch, NoMatchingRenderer, InvalidGetStaticPathsReturn, GetStaticPathsRequired, ImageMissingAlt, and InvalidImageService, which can narrow the fix to configuration, routing, renderer setup, static path data, or image usage before deeper debugging begins.

Then collect environment details in the same categories Astro’s debug providers use: Astro version, Vite version when available, Node version, operating system, package manager, output mode, adapter, and integrations. For build-only failures, pay close attention to whether the route is prerendered and whether the failure is a 500, because the build handler is designed to throw underlying errors rather than hide them behind a generated error page. For development-only failures, inspect Vite SSR metadata and check whether framework component logs are produced during server render, hydration, or both.

Next Steps

Use the official Troubleshooting Guide for debugging techniques, especially terminal versus browser logging and the <Debug /> component. Use the Error Reference when the message includes a named Astro error. If you are preparing a bug report or asking for help, include the debug information categories described above and a minimal reproduction route or component. For adjacent implementation details, read the CLI reference for command-oriented diagnostics, the configuration reference for adapter and output settings, and the routing or content pages when the error involves getStaticPaths(), prerendering, or structured content.