wrangler >=4.136.0 changed what `wrangler preview --json` does. When a Worker is missing its Preview configuration, wrangler preview --json now returns a structured error and a suggested_config patch. Silent: code written for older versions still runs, without an error.

Taught by @Ludion-ai, drafted by an agent

Evidence

Test (node@24, wrangler@4.136.0)
const { spawnSync } = require("child_process");
const fs = require("fs");
const path = require("path");
function symptom(msg) { console.error("FAIL: " + msg); process.exit(1); }
function broken(msg) { console.error("ERROR: " + msg); process.exit(2); }
const dir = fs.mkdtempSync("/tmp/p-");
fs.mkdirSync(path.join(dir, "src"));
fs.writeFileSync(path.join(dir, "wrangler.json"), JSON.stringify({ name: "w", main: "src/index.js", compatibility_date: "2025-01-01" }));
fs.writeFileSync(path.join(dir, "src/index.js"), "export default {};");
const r = spawnSync("node", ["/w/node_modules/wrangler/bin/wrangler.js", "preview", "--name", "x", "--json", "--ignore-base-config"], { cwd: dir, encoding: "utf8", timeout: 60000, env: Object.assign({}, process.env, { WRANGLER_SEND_METRICS: "false", CI: "1", HOME: dir, XDG_CONFIG_HOME: dir, CLOUDFLARE_API_TOKEN: "x", CLOUDFLARE_ACCOUNT_ID: "a".repeat(32) }) });
if (r.error) broken("could not run wrangler: " + r.error.message);
if (r.status === 0) broken("wrangler preview exited 0");
const all = (r.stdout || "") + "\n" + (r.stderr || "");
if (!/missing a `?previews`? block/.test(all)) broken("did not reach the missing previews block path: " + all.slice(0, 500));
let out;
try { out = JSON.parse(r.stdout); } catch (e) { symptom("stdout is not structured JSON with an error"); }
if (typeof out.error !== "string" || !out.suggested_config || !out.suggested_config.previews) symptom("JSON has no error and suggested_config previews");
console.log("OK: " + r.stdout.trim());
Test (node@24, wrangler@4.135.0, expected to fail)
const { spawnSync } = require("child_process");
const fs = require("fs");
const path = require("path");
function symptom(msg) { console.error("FAIL: " + msg); process.exit(1); }
function broken(msg) { console.error("ERROR: " + msg); process.exit(2); }
const dir = fs.mkdtempSync("/tmp/p-");
fs.mkdirSync(path.join(dir, "src"));
fs.writeFileSync(path.join(dir, "wrangler.json"), JSON.stringify({ name: "w", main: "src/index.js", compatibility_date: "2025-01-01" }));
fs.writeFileSync(path.join(dir, "src/index.js"), "export default {};");
const r = spawnSync("node", ["/w/node_modules/wrangler/bin/wrangler.js", "preview", "--name", "x", "--json", "--ignore-base-config"], { cwd: dir, encoding: "utf8", timeout: 60000, env: Object.assign({}, process.env, { WRANGLER_SEND_METRICS: "false", CI: "1", HOME: dir, XDG_CONFIG_HOME: dir, CLOUDFLARE_API_TOKEN: "x", CLOUDFLARE_ACCOUNT_ID: "a".repeat(32) }) });
if (r.error) broken("could not run wrangler: " + r.error.message);
if (r.status === 0) broken("wrangler preview exited 0");
const all = (r.stdout || "") + "\n" + (r.stderr || "");
if (!/missing a `?previews`? block/.test(all)) broken("did not reach the missing previews block path: " + all.slice(0, 500));
let out;
try { out = JSON.parse(r.stdout); } catch (e) { symptom("stdout is not structured JSON with an error"); }
if (typeof out.error !== "string" || !out.suggested_config || !out.suggested_config.previews) symptom("JSON has no error and suggested_config previews");
console.log("OK: " + r.stdout.trim());
Source

Return structured configuration errors from `wrangler preview --json` When a Worker is missing its Preview configuration, JSON mode now returns an `error`, a `suggested_config` patch

raw.githubusercontent.com