Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Cloudflare deploy: framework prerender inside `void deploy`'s build deletes `.wrangler/deploy/config.json` (ENOENT)

Cerrado Apto para principiantes
#463 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@cpojer ya está trabajando en esto.

Desde el 20/10/2026.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
typescript

Línea de trabajo

Empieza con restorePreviewPointer en dist/index.mjs y compara su comprobación del build de deploy con la comprobación del lado del stash descrita en el issue. Ejecuta la reproducción proporcionada con dos builds y luego verifica que .wrangler/deploy/config.json permanezca después del build en modo deploy cuando haya un stash, mientras que el comportamiento de la vista previa manual siga igual.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Problem

In a TanStack Start app with voidPlugin() and TanStack's own build-time prerender (tanstackStart({ prerender: { enabled: true } })), void deploy fails after the build whenever an earlier plain vite build left a stashed pointer in .void/:

[prerender] Prerendered 4 pages:
...
◇ Preparing deployment...
■ ENOENT: no such file or directory, open '<root>/apps/web/.wrangler/deploy/config.json'

TanStack Start prerenders by starting a Vite preview server inside the build process. Void's plugin sees isPreview === true there and runs the preview restore path meant for a manual vite preview, including in the deploy build:

vite build              ── closeBundle: stash .wrangler/deploy/config.json → .void/preview-deploy-config.json
void deploy
  └ child build (VOID_CLOUDFLARE_DEPLOY_BUILD=1)
      ├ build writes a fresh .wrangler/deploy/config.json
      ├ prerender starts a Vite preview server
      │   └ config(): isPreview → restoreCloudflarePreviewPointer()
      │       ├ writes the stash from the earlier build over the pointer
      │       └ process.once("exit", rmSync(.wrangler/deploy/config.json))
      └ child exits → pointer deleted
  └ readGeneratedDeployConfig() → ENOENT

The stash side already skips deploy builds (closeBundle checks VOID_CLOUDFLARE_DEPLOY_BUILD !== "1"). The restore side has no such check (dist/index.mjs, restorePreviewPointer in voidPlugin).

This is the same pointer mechanism as #419, reached from the other direction. There a preview could not find the pointer. Here a preview inside a deploy build removes it.

Repro

A fresh clone reproduces it without void connect and without Cloudflare credentials. The deploy-mode build uses the env void deploy gives its build child.

git clone https://github.com/SweetRetry/void-starter && cd void-starter
git checkout 5230137
pnpm install
cd apps/web
pnpm exec vp build                                                  # plain build, stashes the pointer
VOID_CLOUDFLARE_DEPLOY_BUILD=1 NODE_ENV=production pnpm exec vp build   # what void deploy runs
ls .wrangler/deploy/config.json                                     # missing

Prerender is configured in apps/web/vite.config.ts. The repo's deploy script works around the bug by deleting .void/preview-deploy-config.json first, so call vp build directly as above.

Controls, each starting from an empty .wrangler/deploy and .void/preview-deploy-config.json:

Case Stash before deploy build Prerender Pointer after deploy build
A present on missing
B deleted on present
C present off present

An exit listener registered through NODE_OPTIONS=--require (so it runs before Void's) saw the pointer present in case A. The outer processes then saw it missing, so it is removed by the exit cleanup.

Suggested fix

Skip the restore in deploy builds, the same check the stash side already has:

 const restorePreviewPointer = () => {
   if (!existsSync(join(root, "void.config.ts"))) return;
+  if (process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] === "1") return;
   if (restoreCloudflarePreviewPointer(root) && !scheduledPreviewPointerCleanups.has(root)) {

With this patch applied to dist/index.mjs, case A keeps .wrangler/deploy/config.json ({"configPath":"../../dist/server/wrangler.json"}) after the deploy-mode build. A manual vite preview still finds the build output and gets as far as the remote binding session, which then fails only for lack of an API token in a non-interactive shell. That path runs without the env var, so its code is unchanged.

An alternative is for void deploy to remove .void/preview-deploy-config.json before it starts the build. That is the current workaround.

Question

The framework docs describe routing.prerender (deploy-time edge prerendering) for framework mode and don't mention a framework's own build-time prerender. Is TanStack Start's prerender option a supported setup with Void? We chose it so the blog pages ship as static assets in dist/client and a prerender failure fails the build.

Environment

  • void 1.1.11
  • @tanstack/react-start 1.169.2
  • @cloudflare/vite-plugin 1.64.0, wrangler 4.151.0
  • vite-plus 1.3.0
  • Node 24.14.1, pnpm 12.0.0, macOS
Lenguaje dominante
TypeScript
Estrellas
402
Forks
32
Merge medio
11 h 52 min
PR fusionados (30 d)
88

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de voidzero-dev/void

Todos los issues de voidzero-dev/void

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.