Legacy v3 CLI deployments deprecated server-side

A new server-side gate detects and blocks deployment attempts from legacy v3 CLI versions, prompting developers to upgrade to v4 without risking partial deployment states.
The transition away from the legacy v3 CLI is entering its final phase. Previously, older CLI versions could still attempt deployments, risking incompatible states or hidden failures. A new server-side gate now detects incoming deployment requests from v3 clients and stops them before any database writes or queue enqueues occur.
Enforcement is toggled via a new environment variable. When enabled, the system returns a clear upgrade message pointing to the v4 migration path. Because v4 clients always explicitly declare their deployment type, they pass through unaffected.
Located in the core webapp initialization service, this phased rollout allows legacy traffic to be monitored through logs before flipping the switch to hard enforcement.
View Original GitHub Description
✅ Checklist
- I have followed every step in the contributing guide
- The PR title follows the convention.
- I ran and tested the code works
Summary
Adds a server-side gate that detects deploy attempts from v3 CLI versions (i.e. trigger.dev@3.x) at the POST /api/v1/deployments entry point and, when enabled, rejects them with a clear upgrade message. v4 CLI deploys are completely unaffected.
The last 3.x CLI release was 3.3.7, which we can't update. This approach short-circuits the deploy before any DB writes, image-ref generation, S2 stream creation, or queue enqueue — no side effects in either mode.
How v3 vs v4 are distinguished
I pulled the published CLI tarballs for trigger.dev@3.3.7, 4.0.0, 4.0.1, 4.0.5, 4.1.0, 4.2.0, and the current 4.4.4 in the repo. The cleanest, most reliable signal is the request body to POST /api/v1/deployments:
| Field on initialize | v3.3.7 CLI | v4.x CLI |
|---|---|---|
type | never sent | always sent — "MANAGED" (run_engine_v2) or "V1" |
isNativeBuild / gitMeta / triggeredVia / runtime | not sent | sent |
registryHost / namespace | sent (v3-only; stripped by current Zod schema) | not sent |
Every v4 call site I inspected sets type: features.run_engine_v2 ? "MANAGED" : "V1" unconditionally. payload.type is undefined if and only if the client is a 3.x CLI.
Behavior
-
Detection always runs and emits
logger.warn("Detected deploy from deprecated v3 CLI", { environmentId, projectId, organizationId, enforced }), which lets us watch how many v3 deploys are still happening before enforcement is flipped. -
Enforcement is gated behind
DEPRECATE_V3_CLI_DEPLOYS_ENABLED(default"0", off). When"1", the server returns400with:The trigger.dev CLI v3 is no longer supported for deployments. Please upgrade your project to v4: https://trigger.dev/docs/migrating-from-v3
The v3 CLI surfaces this verbatim as
Failed to start deployment: <message>becausezodfetchthrowsApiErrorfor non-retryable 4xx (400/422) anddeploy.jsin 3.3.7 printserror.message.
Out of scope (intentionally)
api.v1.deployments.$deploymentId.finalize.ts/FinalizeDeploymentService/createDeploymentBackgroundWorkerV3.server.tsare V1-engine paths, not the v3 CLI gate. Leaving them alone per review.- Container-side
createDeploymentBackgroundWorkercall inmanaged-index-controller.tsis still used by v4's in-image indexer. Not touched. - v3
trigger devflow (different code path) — separate deprecation if/when needed.
Testing
- Ran
pnpm run typecheck --filter webapplocally — passes. - Verified v4 tarballs (4.0.0, 4.0.1, 4.0.5, 4.1.0, 4.2.0, 4.4.4) all include
type:in theinitializeDeploymentcall site, so none will be accidentally blocked. - Verified v3.3.7 tarball's
initializeDeploymentpayload has notypefield.
Rollout plan after merge:
- Deploy with
DEPRECATE_V3_CLI_DEPLOYS_ENABLEDunset → watchDetected deploy from deprecated v3 CLIlog volume. - When comfortable, set
DEPRECATE_V3_CLI_DEPLOYS_ENABLED=1to enforce.
Changelog
Detect v3 CLI deploys on /api/v1/deployments and, when DEPRECATE_V3_CLI_DEPLOYS_ENABLED=1, reject them with an upgrade message pointing at https://trigger.dev/docs/migrating-from-v3. v4 CLI deploys are unaffected.
Link to Devin session: https://app.devin.ai/sessions/b242c11bd86e4099aeec8b59bab62143 Requested by: @ericallam