Skip to content

Production is serving stale code: ui:build cannot complete on a clean checkout, so Workers Builds (the deploy path) fails #9731

Description

@JSONbored

Impact

Workers Builds: loopover-ui has failed on every one of the last 25+ commits on main, and it is the deploy path — no GitHub Actions workflow runs wrangler deploy (ui-deploy.yml is named "Validate UI Worker" and only validates).

Production is therefore serving stale code. Two concrete, verifiable examples, both merged to main on 2026-07-28 and neither live:

  • #9574 added fleetAccuracy.basis. Live GET https://api.loopover.ai/v1/public/stats has no basis key.
  • #9594 added the /v1/public/decision-ledger/anchor-payload auth exemption. Live, it still returns 401.

Root cause

The Cloudflare build command is npm run build:cloudflarenpm ci && npm run ui:build.

ui:build runs turbo run build --filter=@loopover/engine, then ui:openapi, whose scripts/write-ui-openapi.ts reaches src/openapi/schemas.ts, which imports @loopover/contract/dist/public-api.js. Nothing in that chain builds @loopover/contract@loopover/engine does not depend on it — so on a clean checkout the import resolves to a directory that was never emitted:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module
  '/opt/buildhome/repo/node_modules/@loopover/contract/dist/public-api.js'
  imported from /opt/buildhome/repo/src/openapi/schemas.ts

It passes in test:ci only by accident of ordering: npm run typecheck runs earlier in that chain, and the //#typecheck turbo task already carries an explicit @loopover/contract#build edge — added for exactly this failure mode, and documented in turbo.json as "the root package.json dependency does NOT create a build edge for a root (//#) task". Cloudflare runs ui:build on its own, so the incidental ordering never applies.

Fix

Add the same edge to ui:build's own turbo invocation — the level that actually owns the dependency.

Verified against a genuinely clean tree (package dist/ and .tsbuildinfo files removed, TURBO_FORCE=1 to defeat the shared worktree cache): without the change ui:build exits 1 on the error above; with it, exit 0 and both dist artifacts are emitted.

Related, worth a separate look

  • Workers Builds: loopover-api fails on the same commits. Whether it shares this root cause is unconfirmed — its build log has not been read.
  • packages/loopover-engine's build does not clear its own .tsbuildinfo (@loopover/contract's build does). Deleting dist/ without deleting .tsbuildinfo makes tsc a silent no-op, so a local "clean rebuild" can appear to succeed while emitting nothing. This masked the reproduction twice before TURBO_FORCE=1 and an explicit .tsbuildinfo sweep. Harmless on a fresh clone; a real trap locally and for any cached CI runner.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions