Running Astro project in a Worker. Local deployment not showing console.log, .warn, .info etc.

I am working on an Astro deployment into Workers. I'm trying to debug talking to a KV binding, but the console isn't showing any outputs. Here is an example of one of my pages. --- import BaseLayout from '../layouts/BaseLayout.astro'; import Header from '../components/Header.astro'; console.log("Loading index page."); --- <BaseLayout title="Jack Portfolio"> <Header /> <main class="d-flex flex-column align-items-center justify-content-center min-vh-100 bg-black text-white"> <img src="/images/jackhome-dark.png" alt="Jack portrait" class="img-fluid" style="max-height: 80vh; object-fit: contain;" /> </main> </BaseLayout> The console.log never shows any output. I've tried .log, .error, .info, .warn. I am running my development server using the following. npx astro build npx wrangler dev I've tried adding --verbose to the wrangler dev command, that didn't help. I am running wrangler 4.20.5. npx version is 10.9.2.
20 Replies
Hello, I’m Allie!
Is this an SSR page? Do you have a repo?
securitypedant
securitypedantOP6mo ago
Repo is private. What’s an SSR page? Ahh server side, yes it’s an Astro page rendered on the server I fixed it, my vscode config wasn't setup correctly. I now have... launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Wrangler Dev (Cloudflare Workers)",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
}
]
}
{
"version": "0.2.0",
"configurations": [
{
"name": "Wrangler Dev (Cloudflare Workers)",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
}
]
}
and in my package.json
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro build && wrangler pages dev",
"astro": "astro",
"deploy": "astro build && wrangler pages deploy",
"cf-typegen": "wrangler types",
"dev:cf": "astro build && wrangler dev"
},
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro build && wrangler pages dev",
"astro": "astro",
"deploy": "astro build && wrangler pages deploy",
"cf-typegen": "wrangler types",
"dev:cf": "astro build && wrangler dev"
},
ugh, but that doesn't support debugging KV... so now if I switch to this config... launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Wrangler Dev (Cloudflare Workers)",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev:cf"
}
]
}
{
"version": "0.2.0",
"configurations": [
{
"name": "Wrangler Dev (Cloudflare Workers)",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev:cf"
}
]
}
package.json
"scripts": {
"dev": "astro dev",
"dev:cf": "astro build && wrangler dev --local",
"build": "astro build",
"preview": "astro build && wrangler pages dev",
"astro": "astro",
"deploy": "astro build && wrangler pages deploy",
"cf-typegen": "wrangler types"
},
"scripts": {
"dev": "astro dev",
"dev:cf": "astro build && wrangler dev --local",
"build": "astro build",
"preview": "astro build && wrangler pages dev",
"astro": "astro",
"deploy": "astro build && wrangler pages deploy",
"cf-typegen": "wrangler types"
},
It launches, but I am no longer able to debug or see console outputs. so I can either debug and see console output, but not be able to interact with KV, or have KV access, but no console or debugging... eek
Hello, I’m Allie!
Is there a reason why dev doesn't work directly?
securitypedant
securitypedantOP6mo ago
What do you mean by directly?
Hello, I’m Allie!
Nvm, just re-read your config. Assuming you are using the Cloudflare Adapter and have a relatively recent version of Astro and wrangler, you should be able to use KV in astro dev Any specific reason you are using pages instead of Workers?
securitypedant
securitypedantOP6mo ago
I’m using workers, it was initially a pages app but I redeployed as a worker
securitypedant
securitypedantOP6mo ago
No description
securitypedant
securitypedantOP6mo ago
so you are saying I should be able to use astro dev instead of wrangler dev and still have access to the KV binding? Because this returns null
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
in astro dev, but works fine in wrangler dev
Hello, I’m Allie!
Weird. Let me try spinning a new instance up and see if I see the same It seems to be working for me? Here's my wrangler.jsonc:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "foo",
"main": "./dist/_worker.js/index.js",
"compatibility_date": "2025-06-20",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"assets": {
"binding": "ASSETS",
"directory": "./dist",
},
"observability": {
"enabled": true,
},
"kv_namespaces": [
{
"binding": "PORTFOLIODATA",
"id": "bar",
},
]
}
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "foo",
"main": "./dist/_worker.js/index.js",
"compatibility_date": "2025-06-20",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"assets": {
"binding": "ASSETS",
"directory": "./dist",
},
"observability": {
"enabled": true,
},
"kv_namespaces": [
{
"binding": "PORTFOLIODATA",
"id": "bar",
},
]
}
In index.astro, I do
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
console.log(raw);
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
console.log(raw);
and I see null in the logs Via astro dev
securitypedant
securitypedantOP6mo ago
Huh, lemme compare differences I a bit. On vacation ok, I get the same. My point being, I can't access the KV when using astro dev, I need to use wrangler dev So I can log and hit breakpoints when using astro dev, but not if I switch to wrangler dev but I need to use wrangler dev to access KV
Hello, I’m Allie!
With the above, KV is functional, at least for me? Even with astro dev It’s printing null because I haven’t yet put anything in the namespace
securitypedant
securitypedantOP6mo ago
hmm strange lemme go back and review my setup running in astro dev, const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos"); This still returns null for me, when I have JSON data in that key. This is my debug code to try and figure out what's going wrong...
onsole.info("Checking if we are a worker.");
if (isCloudflareWorker) {
try {
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");

if (raw === null) {
logMessage = "KV returned null for 'photos'; falling back to local";
photos = localPhotos;
} else {
logMessage = "Getting photos from KV";
photos = JSON.parse(raw);
}
} catch (err) {
logMessage = "Error parsing or loading KV data:";
photos = localPhotos;
}
} else {
logMessage = "Don't seem to be running as a Worker, getting photos from local JSON";
photos = localPhotos;
}
onsole.info("Checking if we are a worker.");
if (isCloudflareWorker) {
try {
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");

if (raw === null) {
logMessage = "KV returned null for 'photos'; falling back to local";
photos = localPhotos;
} else {
logMessage = "Getting photos from KV";
photos = JSON.parse(raw);
}
} catch (err) {
logMessage = "Error parsing or loading KV data:";
photos = localPhotos;
}
} else {
logMessage = "Don't seem to be running as a Worker, getting photos from local JSON";
photos = localPhotos;
}
if you populate that key, can you confirm the JSON is returned? This code also returns no keys...
export async function GET({ locals }) {
const keys = await locals.runtime.env.PORTFOLIODATA.list();
console.log("KV keys:", keys);

const raw = await locals.runtime.env.PORTFOLIODATA.get("photos");
console.log("KV raw data:", raw);

return new Response(raw || "{}", {
headers: { "Content-Type": "application/json" }
});
}
export async function GET({ locals }) {
const keys = await locals.runtime.env.PORTFOLIODATA.list();
console.log("KV keys:", keys);

const raw = await locals.runtime.env.PORTFOLIODATA.get("photos");
console.log("KV raw data:", raw);

return new Response(raw || "{}", {
headers: { "Content-Type": "application/json" }
});
}
Hello, I’m Allie!
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
console.log(`Value from PORTFOLIODATA at key "photos" is "${raw}"`);
const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos");
console.log(`Value from PORTFOLIODATA at key "photos" is "${raw}"`);
Value from PORTFOLIODATA at key "photos" is "THIS_IS_A_STORED_KV_VALUE"
21:53:32 [200] / 7ms
Value from PORTFOLIODATA at key "photos" is "THIS_IS_A_STORED_KV_VALUE"
21:53:32 [200] / 7ms
securitypedant
securitypedantOP6mo ago
Whaaat. So why is my environment not working? Can you drop your code into a quick repo and lemme see if I can run and get the same results
securitypedant
securitypedantOP6mo ago
ok, so I cloned your repo and ran npm install. I edited the wrangler.jsonc and put in my KV id for the binding PORTFOLIODATA, replacing your "bar" placeholder. I then ran npx astro dev, and it started the site. But when I access the home page, I get...
14:25:56 watching for file changes...
Value from PORTFOLIODATA at key "photos" is "null"
14:26:20 [200] / 114ms
14:25:56 watching for file changes...
Value from PORTFOLIODATA at key "photos" is "null"
14:26:20 [200] / 114ms
So what I am doing wrong? What else do I need to check for this to work? I'm running the same code as you. If I run npx astro build, I get an error on the index page.
14:31:24 ▶ src/pages/index.astro
14:31:24 └─ /index.htmlCannot read properties of undefined (reading 'get')
Stack trace:
at file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/dist/_worker.js/pages/index.astro.mjs?time=1750627884372:11:61
at callComponentAsTemplateResultOrResponse (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/runtime/server/render/astro/render.js:91:31)
at renderPage (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/runtime/server/render/page.js:36:30)
at async callMiddleware (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/core/middleware/callMiddleware.js:11:10)
at async generatePath (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/core/build/generate.js:342:16)
14:31:24 ▶ src/pages/index.astro
14:31:24 └─ /index.htmlCannot read properties of undefined (reading 'get')
Stack trace:
at file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/dist/_worker.js/pages/index.astro.mjs?time=1750627884372:11:61
at callComponentAsTemplateResultOrResponse (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/runtime/server/render/astro/render.js:91:31)
at renderPage (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/runtime/server/render/page.js:36:30)
at async callMiddleware (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/core/middleware/callMiddleware.js:11:10)
at async generatePath (file:///Users/simonthorpe/Projects/Development/AstroKVTest/astro-kv-test/node_modules/astro/dist/core/build/generate.js:342:16)
which I assume is complaining about... const raw = await Astro.locals.runtime.env.PORTFOLIODATA.get("photos"); doing a a list of namespaces works from the command line...
npx wrangler kv namespace list
✔ Select an account › Thorpevillage
[
{
"id": "notreal",
"title": "PORTFOLIODATA",
"supports_url_encoding": true,
"beta": false
},
{
"id": "notreal",
"title": "PORTFOLIODATA_preview",
"supports_url_encoding": true,
"beta": false
}
]
npx wrangler kv namespace list
✔ Select an account › Thorpevillage
[
{
"id": "notreal",
"title": "PORTFOLIODATA",
"supports_url_encoding": true,
"beta": false
},
{
"id": "notreal",
"title": "PORTFOLIODATA_preview",
"supports_url_encoding": true,
"beta": false
}
]
and I can list keys...
npx wrangler kv key list --namespace-id notreal --remote
[
{
"name": "films"
},
{
"name": "photos"
}
]
npx wrangler kv key list --namespace-id notreal --remote
[
{
"name": "films"
},
{
"name": "photos"
}
]
I am clearly missing an important step
Hello, I’m Allie!
Oh, you are doing remote
securitypedant
securitypedantOP6mo ago
Doesn’t remote mean it’s using Cloudflare directly? How did you get it working? So I need to tell Astro dev to use remote?
Hello, I’m Allie!
I don’t think Astro can use remote, that’s the issue If you redo the command without remote, it stores the values locally/reads from the local storage
securitypedant
securitypedantOP6mo ago
ahh i see, so I could simply inject the JSON into local storage at time of debug, test the code and then know it works on release Gotcha, so even when using the same namespace id as the production instance, it still just stores it locally? i'll spin up an admin page to inject the test data into storage and it seems that local storage persists between instantiations of the astro dev server

Did you find this page helpful?