wrangler >=4.116.0 changed what `deploy` does. Wrangler deploy automatically registers the project-derived workers.dev account subdomain on a first deploy when running in a detected agent environment. 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.116.0)
const fs = require("fs");
const http = require("http");
const { spawn } = require("child_process");
function symptom(msg) { console.error("FAIL: " + msg); process.exit(1); }
function broken(msg) { console.error("ERROR: " + msg); process.exit(2); }
const ACC = "0123456789abcdef0123456789abcdef";
const dir = "/tmp/proj";
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(dir + "/package.json", JSON.stringify({ name: "agent-proj", private: true }));
fs.writeFileSync(dir + "/index.js", "export default { fetch() { return new Response('hi'); } };\n");
fs.writeFileSync(dir + "/wrangler.json", JSON.stringify({ name: "cfg-worker", main: "index.js", compatibility_date: "2025-01-01" }));
const seen = [];
let put = null;
let out = "";
let child = null;
let done = false;
function send(res, status, body) { res.writeHead(status, { "content-type": "application/json" }); res.end(JSON.stringify(body)); }
function err(res, status, code, message) { send(res, status, { success: false, errors: [{ code, message }], messages: [], result: null }); }
const server = http.createServer((req, res) => {
  let body = "";
  req.on("data", (c) => (body += c));
  req.on("end", () => {
    const p = req.url.split("?")[0].replace(/^\/client\/v4/, "");
    seen.push(req.method + " " + p);
    if (req.method === "GET" && p === "/accounts/" + ACC + "/workers/services/cfg-worker") return err(res, 404, 10090, "This Worker does not exist on your account.");
    if (req.method === "GET" && p === "/accounts/" + ACC + "/workers/subdomain") return err(res, 404, 10007, "workers.dev subdomain not found");
    if (req.method === "GET" && p.startsWith("/accounts/" + ACC + "/workers/subdomains/")) return send(res, 200, { success: true, errors: [], messages: [], result: {} });
    if (req.method === "PUT" && p === "/accounts/" + ACC + "/workers/subdomain") {
      try { put = JSON.parse(body); } catch { put = { raw: body }; }
      send(res, 200, { success: true, errors: [], messages: [], result: { subdomain: put.subdomain } });
      setTimeout(finish, 1500);
      return;
    }
    return err(res, 404, 10000, "not mocked: " + req.method + " " + p);
  });
});
function finish() {
  if (done) return;
  done = true;
  if (child && child.exitCode === null) child.kill("SIGKILL");
  server.close();
  const tail = out.slice(-1500);
  if (put) {
    if (put.subdomain !== "agent-proj") broken("wrangler deploy registered an unexpected workers.dev subdomain: " + JSON.stringify(put) + "\n" + tail);
    console.log("OK: wrangler deploy in an agent environment registered the workers.dev subdomain agent-proj without prompting");
    process.exit(0);
  }
  const askedSubdomain = seen.includes("GET /accounts/" + ACC + "/workers/subdomain");
  if (askedSubdomain && /register a workers\.dev subdomain/.test(out)) symptom("wrangler deploy in an agent environment did not register a workers.dev subdomain; it stopped asking the user to register one");
  broken("wrangler deploy ended unexpectedly; requests: " + seen.join(", ") + "\n" + tail);
}
server.listen(0, "127.0.0.1", () => {
  const port = server.address().port;
  const env = Object.assign({}, process.env, {
    HOME: "/tmp",
    CLAUDECODE: "1",
    CLOUDFLARE_API_TOKEN: "test-token",
    CLOUDFLARE_ACCOUNT_ID: ACC,
    CLOUDFLARE_API_BASE_URL: "http://127.0.0.1:" + port + "/client/v4",
    WRANGLER_SEND_METRICS: "false",
    NO_COLOR: "1",
    FORCE_COLOR: "0",
  });
  for (const k of ["CI", "CONTINUOUS_INTEGRATION", "BUILD_NUMBER", "RUN_ID", "GITHUB_ACTIONS", "WORKERS_CI", "WRANGLER_CI_MATCH_TAG"]) delete env[k];
  child = spawn(process.execPath, ["/w/node_modules/wrangler/bin/wrangler.js", "deploy"], { cwd: dir, env, stdio: ["ignore", "pipe", "pipe"] });
  child.stdout.on("data", (d) => (out += d));
  child.stderr.on("data", (d) => (out += d));
  child.on("error", (e) => broken("could not start wrangler: " + e.message));
  child.on("exit", () => setTimeout(finish, 200));
});
setTimeout(() => { if (!done) { out += "\n[timeout]"; finish(); } }, 75000);
Test (node@24, wrangler@4.115.0, expected to fail)
const fs = require("fs");
const http = require("http");
const { spawn } = require("child_process");
function symptom(msg) { console.error("FAIL: " + msg); process.exit(1); }
function broken(msg) { console.error("ERROR: " + msg); process.exit(2); }
const ACC = "0123456789abcdef0123456789abcdef";
const dir = "/tmp/proj";
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(dir + "/package.json", JSON.stringify({ name: "agent-proj", private: true }));
fs.writeFileSync(dir + "/index.js", "export default { fetch() { return new Response('hi'); } };\n");
fs.writeFileSync(dir + "/wrangler.json", JSON.stringify({ name: "cfg-worker", main: "index.js", compatibility_date: "2025-01-01" }));
const seen = [];
let put = null;
let out = "";
let child = null;
let done = false;
function send(res, status, body) { res.writeHead(status, { "content-type": "application/json" }); res.end(JSON.stringify(body)); }
function err(res, status, code, message) { send(res, status, { success: false, errors: [{ code, message }], messages: [], result: null }); }
const server = http.createServer((req, res) => {
  let body = "";
  req.on("data", (c) => (body += c));
  req.on("end", () => {
    const p = req.url.split("?")[0].replace(/^\/client\/v4/, "");
    seen.push(req.method + " " + p);
    if (req.method === "GET" && p === "/accounts/" + ACC + "/workers/services/cfg-worker") return err(res, 404, 10090, "This Worker does not exist on your account.");
    if (req.method === "GET" && p === "/accounts/" + ACC + "/workers/subdomain") return err(res, 404, 10007, "workers.dev subdomain not found");
    if (req.method === "GET" && p.startsWith("/accounts/" + ACC + "/workers/subdomains/")) return send(res, 200, { success: true, errors: [], messages: [], result: {} });
    if (req.method === "PUT" && p === "/accounts/" + ACC + "/workers/subdomain") {
      try { put = JSON.parse(body); } catch { put = { raw: body }; }
      send(res, 200, { success: true, errors: [], messages: [], result: { subdomain: put.subdomain } });
      setTimeout(finish, 1500);
      return;
    }
    return err(res, 404, 10000, "not mocked: " + req.method + " " + p);
  });
});
function finish() {
  if (done) return;
  done = true;
  if (child && child.exitCode === null) child.kill("SIGKILL");
  server.close();
  const tail = out.slice(-1500);
  if (put) {
    if (put.subdomain !== "agent-proj") broken("wrangler deploy registered an unexpected workers.dev subdomain: " + JSON.stringify(put) + "\n" + tail);
    console.log("OK: wrangler deploy in an agent environment registered the workers.dev subdomain agent-proj without prompting");
    process.exit(0);
  }
  const askedSubdomain = seen.includes("GET /accounts/" + ACC + "/workers/subdomain");
  if (askedSubdomain && /register a workers\.dev subdomain/.test(out)) symptom("wrangler deploy in an agent environment did not register a workers.dev subdomain; it stopped asking the user to register one");
  broken("wrangler deploy ended unexpectedly; requests: " + seen.join(", ") + "\n" + tail);
}
server.listen(0, "127.0.0.1", () => {
  const port = server.address().port;
  const env = Object.assign({}, process.env, {
    HOME: "/tmp",
    CLAUDECODE: "1",
    CLOUDFLARE_API_TOKEN: "test-token",
    CLOUDFLARE_ACCOUNT_ID: ACC,
    CLOUDFLARE_API_BASE_URL: "http://127.0.0.1:" + port + "/client/v4",
    WRANGLER_SEND_METRICS: "false",
    NO_COLOR: "1",
    FORCE_COLOR: "0",
  });
  for (const k of ["CI", "CONTINUOUS_INTEGRATION", "BUILD_NUMBER", "RUN_ID", "GITHUB_ACTIONS", "WORKERS_CI", "WRANGLER_CI_MATCH_TAG"]) delete env[k];
  child = spawn(process.execPath, ["/w/node_modules/wrangler/bin/wrangler.js", "deploy"], { cwd: dir, env, stdio: ["ignore", "pipe", "pipe"] });
  child.stdout.on("data", (d) => (out += d));
  child.stderr.on("data", (d) => (out += d));
  child.on("error", (e) => broken("could not start wrangler: " + e.message));
  child.on("exit", () => setTimeout(finish, 200));
});
setTimeout(() => { if (!done) { out += "\n[timeout]"; finish(); } }, 75000);
Source

automatically registers the same project-derived workers.dev account subdomain on a first deploy when running in a detected agent environment.

raw.githubusercontent.com