Skip to content

Fix Astro.logger producing no output in dev with the Cloudflare adapter - #17853

Open
wakqasahmed wants to merge 2 commits into
withastro:mainfrom
wakqasahmed:fix/issue-17823-logger-cloudflare
Open

Fix Astro.logger producing no output in dev with the Cloudflare adapter#17853
wakqasahmed wants to merge 2 commits into
withastro:mainfrom
wakqasahmed:fix/issue-17823-logger-cloudflare

Conversation

@wakqasahmed

Copy link
Copy Markdown
Contributor

Changes

Fixes #17823.

createConsoleLogger takes an options object ({ level }), but the non-runnable dev entrypoint was calling it with the bare level string:

setLogger(manifest, createConsoleLogger(manifest.logLevel));

Destructuring { level } out of a string yields undefined, so the logger was constructed with no level. Every call then goes through isLogLevelEnabled(undefined, level), which evaluates levels[undefined] <= levels[level]undefined <= 30 is false — so every message is dropped before it ever reaches the destination. That is why Astro.logger / context.logger are completely silent while console.log still shows up.

This only affects adapters whose dev server runs in a non-runnable environment (workerd, i.e. @astrojs/cloudflare), because that path loads astro/app/entrypoint/dev (core/app/entrypoints/virtual/dev.ts). The Node adapter's dev server goes through vite-plugin-app/createAstroServerApp.ts, which injects an already-constructed logger, so it was never affected — matching the report.

The fix is to pass the options object the function actually expects.

Testing

Added packages/astro/test/units/logger/dev-entrypoint.test.ts, which stubs the virtual:astro:manifest / virtual:astro:fetchable modules via registerHooks, calls createApp() from the dev entrypoint, and asserts the manifest's logger reports the configured level and actually emits both error and info records.

  • The new test fails against the old code (logger.level() is undefined and nothing is written) and passes with the fix.
  • packages/astro logger unit tests: 88 passing, 0 failing.
  • Full pnpm --filter astro test:unit: 3360 tests, 3359 passing, 0 failing.
  • tsc -b on packages/astro is clean.

Docs

No docs change needed — this restores documented Astro.logger behaviour rather than changing it.

@changeset-bot

changeset-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 11e1396

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 421 packages
Name Type
astro Patch
@e2e/astro-linked-lib Patch
@e2e/actions-blog Patch
@e2e/actions-react-19 Patch
@e2e/astro-component Patch
@e2e/astro-envs Patch
@e2e/astro-island-hydration-error Patch
@test/astro-cloudflare-node-prerender-mdx Patch
@test/astro-cloudflare Patch
@e2e/content-collections Patch
@e2e/csp-server-islands Patch
@e2e/css Patch
@test/custom-client-directives Patch
@e2e/dev-toolbar Patch
@e2e/error-cyclic Patch
@e2e/error-sass Patch
@e2e/errors Patch
@e2e/hydration-race Patch
@e2e/i18n Patch
@test/nested-style-bug-e22e Patch
@e2e/preact-compat-component Patch
@e2e/preact-component Patch
@e2e/preact-lazy-component Patch
@e2e/prefetch Patch
@e2e/react-component Patch
@e2e/server-islands-key Patch
@e2e/server-islands Patch
@e2e/solid-circular Patch
@e2e/solid-component Patch
@e2e/solid-recurse Patch
@e2e/svelte-component Patch
@e2e/e2e-tailwindcss Patch
@e2e/ts-resolution Patch
@e2e/view-transitions Patch
@e2e/vue-component Patch
@performance/md Patch
@performance/mdoc Patch
@performance/mdx Patch
@test/0-css Patch
fake-astro-library Patch
@test/actions Patch
@test/alias-css-url-data-uri Patch
@test/alias-css-url Patch
@test/alias-path-alias-style Patch
@test/ts-paths-no-baseurl Patch
@test/aliases-tsconfig Patch
@test/aliases Patch
@test/api-routes Patch
@test/asset-query-params-chunks Patch
@test/asset-url-base Patch
@test/astro-pages Patch
@test/astro-assets-prefix Patch
@test/astro-assets Patch
@test/astro-basic Patch
@test/astro-check-errors Patch
@test/astro-check-no-errors Patch
@test/astro-check-watch Patch
@test/astro-children Patch
@test/astro-client-only Patch
@test/astro-component-bundling Patch
@test/astro-component-code Patch
@test/astro-css-bundling Patch
@test/astro-dev-headers Patch
@test/astro-dev-http2 Patch
@test/astro-doctype Patch
@test/astro-dynamic Patch
@test/astro-env-content-collections Patch
@test/astro-env-required-public Patch
@test/astro-env-server-fail Patch
@test/astro-env-server-secret Patch
@test/astro-env Patch
@test/astro-envs Patch
@test/astro-expr Patch
@test/astro-get-static-paths Patch
@test/astro-head Patch
@test/astro-manifest-client-script Patch
@test/astro-manifest-invalid Patch
@test/astro-manifest Patch
@test/astro-markdown-frontmatter-injection Patch
@test/astro-markdown-plugins Patch
@test/astro-markdown-remarkRehype Patch
@test/astro-markdown-skiki-default-color Patch
@test/astro-markdown-skiki-langs Patch
@test/astro-markdown-skiki-themes-custom Patch
@test/astro-markdown-skiki-themes-integrated Patch
@test/astro-markdown-skiki-wrap-false Patch
@test/astro-markdown-skiki-wrap-null Patch
@test/astro-markdown-skiki-wrap-true Patch
@test/astro-markdown-url Patch
@test/astro-markdown Patch
@test/astro-mode Patch
@test/astro-page-directory-url Patch
@test/astro-partial-html Patch
@test/astro-preview-allowed-hosts Patch
@test/astro-preview-headers Patch
@test/astro-public Patch
@test/astro-script-template-dedup Patch
@test/astro-scripts Patch
@test/astro-slots-nested Patch
@test/concurrency Patch
@test/build-readonly-file Patch
@test/cache-memory-query-include Patch
@test/cache-memory-query Patch
@test/client-address-node Patch
@test/client-only-child-styles Patch
@test/client-only-css-chunk-leak Patch
@test/code-component Patch
@test/component-library Patch
@test/config-vite-css-target-no-minify Patch
@test/config-vite-css-target Patch
@test/config-vite Patch
@test/react-container Patch
@test/content-with-spaces-in-folder-name Patch
@test/content-collection-picture-render Patch
@example/content-collection-references Patch
@test/content-collection-tla-svg Patch
@test/content-collections-base Patch
@test/content-collections-empty-dir Patch
@test/content-collections-empty-md-file Patch
@test/content-collections-image-hmr Patch
@test/content-collections-mutation Patch
@test/content-collections-number-id Patch
@test/content-collections-type-inference Patch
@test/content-collections-with-config-mjs Patch
@test/content-collections Patch
@test/content-frontmatter Patch
@test/content-intellisense Patch
@test/content-layer-loader-schema-function Patch
@test/content-layer-remark-plugins Patch
@test/content-layer Patch
@test/content-ssr-integration Patch
@test/content-static-paths-integration Patch
@test/content Patch
@test/core-image-data-url Patch
@test/core-image-deletion-ssr Patch
@test/core-image-deletion Patch
@test/core-image-errors Patch
@test/core-image-fs-config Patch
@test/core-image-remark-infersize Patch
@test/core-image-layout Patch
@test/core-image-picture-emit-file Patch
@test/core-image-remark-imgattr Patch
@test/core-image-ssg Patch
@test/core-image-ssr Patch
@test/core-image-svg-in-client Patch
@test/core-image-svg Patch
@test/core-image-unconventional-settings Patch
@test/core-image Patch
@test/csp-adapter Patch
@test/csp-fonts Patch
@test/csp Patch
@test/css-assets Patch
@test/css-dangling-references Patch
@test/css-deduplication Patch
@test/css-double-bundle Patch
@test/css-dynamic-import-dev Patch
@test/css-import-as-inline Patch
@test/css-inline-stylesheets Patch
@test/css-no-code-split Patch
@test/css-path-case Patch
@test/css-pure-chunk-query-params Patch
@test/css-server-output-dedup Patch
@test/custom-404-injected-from-dep Patch
@test/custom-404-pkg Patch
custom-fetch-error-pages Patch
@test/custom-renderer Patch
@test/data-collections-schema Patch
@test/data-collections Patch
@test/debug-component Patch
@test/dev-container Patch
@test/dev-render Patch
@test/dev-request-url Patch
@test/dynamic-endpoint-collision Patch
@test/dynamic-route-build-file Patch
@test/endpoint-routing Patch
@test/error-bad-js Patch
@test/error-build-location Patch
@test/error-non-error Patch
@test/extension-matching Patch
@test/fetch Patch
@test/fonts Patch
@test/astro-fontsource-package Patch
@test/get-static-paths-pages Patch
@test/glob-pages-css Patch
@test/head-propagation-prerender-env Patch
@test/hmr-markdown Patch
@test/hmr-middleware Patch
@test/hmr-new-page Patch
@test/hmr-slots-render Patch
@test/hoisted-imports Patch
@test/html-component Patch
@test/html-escape Patch
@test/html-page Patch
@test/html-slots Patch
@test/hydration-race Patch
@test/i18n-client-import Patch
@test/i18n-css-leak-basic Patch
@test/import-ts-with-js Patch
@test/impostor-md-file Patch
@test/incremental-build-client-only Patch
@test/incremental-build-concurrency Patch
@test/incremental-build-content Patch
@test/incremental-build-drop-key Patch
@test/incremental-build-dynamic-import Patch
@test/incremental-build-fonts Patch
@test/incremental-build-headers Patch
@test/incremental-build-images Patch
@test/incremental-build-islands Patch
@test/incremental-build-no-output Patch
@test/incremental-build-script Patch
@test/incremental-build Patch
@test/integration-add-page-extension Patch
@test/integration-server-setup Patch
@test/jsx-queue-rendering Patch
@test/large-array-solid Patch
@test/legacy-collections-backwards-compat Patch
@test/lightningcss-css-modules-content Patch
@test/lightningcss-scoped-nesting Patch
@test/live-loaders Patch
@test/markdown Patch
@test/middleware-dev Patch
@test/middleware-full-ssr Patch
@test/middleware-no-user-middlewaqre Patch
@test/middleware-tailwind Patch
@test/minification-html-default Patch
@test/minification-html-jsx Patch
@test/minification-html Patch
@test/non-ascii-path Patch
@test/non-html-pages Patch
@test/page-format Patch
@test/page-level-styles Patch
@test/parallel-components Patch
@test/partials-css-boundary Patch
@test/partials Patch
@test/passthrough-image-service Patch
@test/postcss Patch
@test/preact-compat-component Patch
@test/preact-component Patch
@test/remote-css Patch
@test/request-signal Patch
@test/reuse-injected-entrypoint Patch
@test/root-srcdir-css Patch
@test/scoped-style-strategy Patch
@test/server-entry-fake-adapter Patch
@test/server-entry Patch
@test/server-islands-hybrid Patch
@test/server-islands-ssr Patch
@test/session-false Patch
@test/session-tree-shake Patch
@test/sessions Patch
@test/slots-preact Patch
@test/slots-react Patch
@test/slots-solid Patch
@test/slots-svelte Patch
@test/slots-vue Patch
@test/solid-component Patch
@test/sourcemap Patch
@test/space-in-folder-name Patch
@test/special-chars-in-component-imports Patch
@test/ssr-assets Patch
@test/ssr-dynamic Patch
@test/ssr-partytown Patch
@test/ssr-prerender-get-static-paths Patch
@test/ssr-prerender Patch
@test/ssr-preview Patch
@test/ssr-renderers-static-vue Patch
@test/ssr-request Patch
@test/ssr-hoisted-script Patch
@test/ssr-scripts Patch
@test/static-build-code-component Patch
@test/static-build-dir Patch
@test/static-build-frameworks Patch
@test/static-build-page-url-format Patch
@test/static-build-ssr Patch
@test/static-build Patch
@test/static-redirect Patch
@test/svelte-component Patch
@test/svg-deduplication Patch
@test/tailwindcss Patch
@e2e/third-party-astro Patch
@test/url-import-suffix Patch
@test/view-transitions Patch
@test/virtual-astro-file Patch
@test/vite-virtual-modules Patch
@test/vitest Patch
@test/vue-component Patch
@test/vue-with-multi-renderer Patch
@test/alpinejs-basics Patch
@test/alpinejs-directive Patch
@test/alpinejs-plugin-script-import Patch
@test/astro-cloudflare-allowed-hosts Patch
@test/astro-cloudflare-astro-dev-platform Patch
@test/astro-cloudflare-astro-env Patch
@test/astro-cloudflare-binding-image-cache Patch
@test/astro-cloudflare-binding-image-service Patch
@test/astro-cloudflare-cache-provider-wait-until Patch
@test/astro-cloudflare-cache-provider Patch
@test/astro-cloudflare-client-address Patch
@test/astro-cloudflare-compile-custom-image-service Patch
@test/astro-cloudflare-compile-image-service Patch
@test/astro-cloudflare-custom-entryfile-fetch-state Patch
@test/astro-cloudflare-custom-entryfile Patch
@test/astro-cloudflare-custom-image-service Patch
@test/astro-cloudflare-dev-image-endpoint Patch
@test/astro-cloudflare-dev-logger Patch
@test/astro-cloudflare-external-image-service Patch
@test/astro-cloudflare-external-redirects Patch
@test/cloudflare-incremental-images Patch
@test/astro-cloudflare-internal-redirects Patch
@test/astro-cloudflare-no-output Patch
@test/astro-cloudflare-prerender-node-env Patch
@test/astro-cloudflare-prerender-queue-consumers Patch
@test/astro-cloudflare-prerender-styles Patch
@test/astro-cloudflare-prerenderer-errors Patch
@test/astro-cloudflare-prerenderer-render-error Patch
@test/routing-priority-cloudflare Patch
@test/cf-server-entry Patch
@test/astro-cloudflare-server-island-prerender-framework Patch
@test/astro-cloudflare-sql-import Patch
@test/cf-ssr-deps Patch
@test/astro-cloudflare-static Patch
@test/astro-cloudflare-svelte-rune-deps Patch
@test/astro-cloudflare-top-level-return Patch
@test/cf-user-optimize-deps Patch
@test/astro-cloudflare-vite-plugin Patch
@test/astro-cloudflare-with-base Patch
@test/astro-cloudflare-with-react Patch
@test/astro-cloudflare-with-solid-js Patch
@test/astro-cloudflare-with-svelte Patch
@test/astro-cloudflare-with-vue Patch
@test/astro-cloudflare-wrangler-preview-platform Patch
@test/markdoc-content-collections Patch
@test/content-layer-markdoc Patch
@test/headings-custom Patch
@test/headings Patch
@test/image-assets-custom Patch
@test/image-assets Patch
@test/markdoc-propagated-assets Patch
@test/markdoc-render-with-space Patch
@test/markdoc-render-html Patch
@test/markdoc-render-null Patch
@test/markdoc-render-partials Patch
@test/markdoc-render-simple Patch
@test/markdoc-render-table-attrs Patch
@test/markdoc-render-this-context Patch
@test/markdoc-render-typographer Patch
@test/markdoc-render-with-components Patch
@test/markdoc-render-with-config Patch
@test/markdoc-render-with-extends-components Patch
@test/markdoc-render-with-indented-components Patch
@test/markdoc-render-with-transform Patch
@test/markdoc-variables Patch
@test/content-layer-rendering Patch
@test/mdx-css-head-mdx Patch
@test/image-remark-imgattr Patch
@test/mdx-astro-container-escape Patch
@test/mdx-frontmatter-injection Patch
@test/netlify-skew-protection Patch
@test/netlify-hosted-astro-project Patch
@test/nodejs-api-route Patch
@test/nodejs-badurls Patch
@test/nodejs-encoded Patch
@test/nodejs-errors Patch
@test/nodejs-headers Patch
@test/nodejs-image Patch
@test/locals Patch
@test/node-middleware Patch
@test/nodejs-prerender-404-500 Patch
@test/nodejs-prerender Patch
@test/nodejs-prerendered-error-page-fetch Patch
@test/nodejs-preview-headers Patch
@test/redirects Patch
@test/node-sessions Patch
@test/ssr-assets-middleware Patch
@test/node-static-headers Patch
@test/node-trailingslash Patch
@test/url Patch
@test/well-known-locations Patch
@test/react-component Patch
@test/sitemap-chunks Patch
@test/sitemap-dynamic Patch
@test/sitemap-i18n-fallback Patch
@test/sitemap-ssr Patch
@test/sitemap-static Patch
@test/sitemap-trailing-slash Patch
async-rendering Patch
conditional-rendering Patch
@test/empty-class Patch
svelte-prop-types Patch
@test/astro-vercel-basic Patch
@test/astro-vercel-image Patch
@test/astro-vercel-integration-assets Patch
@test/vercel-isr Patch
@test/vercel-max-duration Patch
@test/vercel-edge-middleware-with-edge-file Patch
@test/vercel-edge-middleware-without-edge-file Patch
@test/astro-vercel-no-output Patch
@test/astro-vercel-prerendered-error-pages Patch
@test/astro-vercel-redirects-serverless Patch
@test/astro-vercel-redirects Patch
@test/vercel-server-islands-static Patch
@test/vercel-server-islands Patch
@test/astro-vercel-serverless-prerender Patch
@test/astro-vercel-serverless-with-dynamic-routes Patch
@test/astro-vercel-static-assets Patch
@test/vercel-static-headers Patch
@test/astro-vercel-static Patch
@test/vercel-streaming Patch
@test/astro-vercel-with-web-analytics-enabled-output-as-static Patch
vercel-hosted-astro-project Patch
@test/vue-app-entrypoint-async Patch
@test/vue-app-entrypoint-css Patch
@test/vue-app-entrypoint-no-export-default Patch
@test/vue-app-entrypoint-relative Patch
@test/vue-app-entrypoint-src-absolute Patch
@test/vue-app-entrypoint Patch
@test/vue-basics Patch
vue-prop-types Patch
astro-benchmark Patch
@benchmark/adapter Patch
@benchmark/timer Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the pkg: astro Related to the core `astro` package (scope) label Aug 28, 2026
@codspeed-hq

codspeed-hq Bot commented Aug 28, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 15.55%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 20 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation Build: hybrid site (static + server) 1.4 s 1.7 s -15.55%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing wakqasahmed:fix/issue-17823-logger-cloudflare (11e1396) with main (f8e9458)

Open in CodSpeed

export const createApp: CreateApp = ({ streaming } = {}) => {
// Composition order: logger → environment → facade ctor
// (which warms the route table) → fetch handler → HMR wiring.
setLogger(manifest, createConsoleLogger(manifest.logLevel));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised this didn't throw a typescript error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and the answer turned out to be a real hole rather than a loose signature.

createConsoleLogger is properly typed — packages/astro/src/core/logger/impls/console.ts:38 declares createConsoleLogger({ level }: { level: AstroLoggerLevel }). The problem was on the other side: manifest was any at this call site, so nothing was being compared.

It came from packages/astro/dev-only.d.ts:

declare module 'virtual:astro:manifest' {
	import type { SSRManifest } from './src/index.js';
	export const manifest: SSRManifest;
}

A top-level relative import inside an ambient declare module block is not legal — TS reports TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name plus TS2307 on ./src/index.js. Because configs/tsconfig.base.json sets skipLibCheck: true, both errors are swallowed (they live in a .d.ts), SSRManifest degrades to any, and so does the exported manifest. You can see it directly — with the original declaration, const x: number = manifest.logLevel type-checks fine inside src/, while importing SSRManifest from ../../../../index.js in the same file correctly errors with Type 'string' is not assignable to type 'number'.

I've switched that one declaration to the inline import(...) type form, which is valid in an ambient module:

export const manifest: import('./src/index.js').SSRManifest;

With that in place, tsc -b on the original code now fails exactly where you'd expect:

src/core/app/entrypoints/virtual/dev.ts(24,42): error TS2345: Argument of type 'string' is not assignable to parameter of type '{ level: AstroLoggerLevel; }'.

and passes with the fix. So the bug is now guarded by the compiler rather than only by a test.

One thing worth flagging separately: eight other declarations in dev-only.d.ts have the same problem (actions/entrypoint, routes, renderers, middleware, session-driver, dev-css, dev-css-all, component-metadata), and virtual:astro:adapter-entrypoint has export default any; which is TS2693. Converting all of them surfaces further pre-existing type errors — virtual:astro:routes is declared as RoutesList[] but both dev.ts and createAstroServerApp.ts consume it as RouteInfo[], and ImportedDevStyles no longer exists in src/types/astro.ts. That felt out of scope for a logger fix, so I left it alone; happy to open a separate issue or PR for it if you'd like.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're trying to make a test unit when it's supposed to be integration. Please remove those stubs and redesign the test

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, and you were right that the stubs were papering over the thing that actually needed testing. I've deleted packages/astro/test/units/logger/dev-entrypoint.test.ts along with the whole stubs/ directory and the registerHooks resolver, and replaced it with a real integration test.

The new test is packages/integrations/cloudflare/test/dev-logger.test.ts, with a fixture at test/fixtures/dev-logger/. That's the only place in the repo where the non-runnable dev entrypoint is genuinely exercised — vite-plugin-app resolves virtual:astro:app to astro/app/entrypoint/dev when command === 'serve', and the Cloudflare adapter is what puts a real worker in front of it. It follows the pattern of the existing dev-server tests there (dev-image-endpoint.test.ts, astro-dev-platform.test.ts): loadFixture plus startDevServer, then a real fetch. Nothing is mocked, stubbed, or resolver-patched.

The assertion is on real output rather than on internal state. The console logger writes inside the worker, whose stdout is not the test process's stdout, so the fixture page captures its own console.info/console.error around two Astro.logger calls and renders what was written; the test reads that back out of the HTML. One detail worth noting in case it looks odd: the fixture is loaded with logLevel: 'info', because loadFixture defaults every fixture to 'silent', which would have suppressed the records for an entirely legitimate reason and made the test green regardless.

I verified it fails for the right reason. With createConsoleLogger(manifest.logLevel) restored and the fixture's Vite dep cache cleared, the test fails with Expected two log records, got [] — matching the reported symptom, since isLogLevelEnabled(undefined, 'info') evaluates undefined <= 30 and drops every record. With the fix, both records come through.

The unit test that remains is the compile-time one described in the other thread: with the virtual:astro:manifest declaration corrected, tsc -b now rejects the original call outright.

@github-actions github-actions Bot added the pkg: integration Related to any renderer integration (scope) label Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: astro Related to the core `astro` package (scope) pkg: integration Related to any renderer integration (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Astro.logger not working with Cloudflare Adapter

2 participants