Skip to content

fix(cli): handle catalog: protocol in dependency update check (#3905) - #4965

Closed
kaiizer777 wants to merge 1 commit into
triggerdotdev:mainfrom
kaiizer777:fix/cli-catalog-protocol-crash
Closed

kaiizer777 wants to merge 1 commit into
triggerdotdev:mainfrom
kaiizer777:fix/cli-catalog-protocol-crash

Conversation

@kaiizer777

Copy link
Copy Markdown

Overview

Fixes #3905

In bun and pnpm monorepos utilizing workspace catalogs, dependencies in package.json are specified with catalog protocols (e.g. "@trigger.dev/sdk": "catalog:" or "catalog:<catalog-name>").

When running CLI commands such as trigger dev, trigger deploy, or trigger update, updateTriggerPackages() checks for version mismatches:

  1. getTriggerDependencies() previously only skipped dependencies starting with "workspace", but did not filter out "catalog:" specifiers. If local resolution failed to resolve the local installed package path, "catalog:" was retained as the dependency version.
  2. In getVersionMismatches(), semver.minVersion(dep.version) was called directly on "catalog:", which threw an unhandled TypeError: Invalid comparator: catalog:, crashing the CLI process immediately.

Changes

  • In packages/cli-v3/src/commands/update.ts:
    • Updated getTriggerDependencies() to skip catalog: dependencies in addition to workspace dependencies.
    • Defensively guarded getVersionMismatches() with semver.validRange(dep.version) and wrapped semver.minVersion(dep.version) in a try...catch block to gracefully skip non-standard or unresolvable version specifiers without throwing.
    • Exported Dependency, getVersionMismatches, and getTriggerDependencies for direct unit testing.
  • Added unit tests in packages/cli-v3/src/commands/update.test.ts verifying that catalog: and workspace: protocols are handled cleanly without throwing, and that getVersionMismatches() never crashes on non-semver strings.
  • Added patch changeset for trigger.dev.

Note

A vouch request is already open at #4963.

@changeset-bot

changeset-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8499022

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 27 packages
Name Type
trigger.dev Patch
@internal/dashboard-agent Patch
@trigger.dev/build Patch
@trigger.dev/core Patch
@trigger.dev/python Patch
@trigger.dev/react-hooks Patch
@trigger.dev/redis-worker Patch
@trigger.dev/rsc Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer Patch
@trigger.dev/rbac Patch
@trigger.dev/sso Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/metrics-pipeline Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/run-store Patch
@internal/schedule-engine Patch
@internal/tracing Patch
@internal/webhook-engine Patch
@internal/webhook-sources Patch
@internal/testcontainers Patch
@internal/cache Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Hi @kaiizer777, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions Bot closed this Sep 20, 2026
@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 1604f5e2-f9e1-40a3-9881-43af6444357c

📥 Commits

Reviewing files that changed from the base of the PR and between 414e5a2 and 8499022.

📒 Files selected for processing (3)
  • .changeset/cli-catalog-protocol-crash.md
  • packages/cli-v3/src/commands/update.test.ts
  • packages/cli-v3/src/commands/update.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review

Comment on lines +343 to 345
if (version.startsWith("workspace") || version.startsWith("catalog:")) {
continue;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Catalog dependencies bypass version enforcement

With installed catalog dependencies, getTriggerDependencies drops them before resolving their concrete versions. dev, deploy, and update then accept incompatible Trigger.dev package versions without warning or updating them.

Learn more

Catalog specifiers such as catalog: name a version stored in workspace configuration. They are not evidence that the installed package matches the CLI. The existing resolver can recover that package's concrete installed version, and previously did so whenever resolution succeeded. Returning early now removes the dependency from both mismatch detection and the required update gate.

Example: A workspace catalog pins @trigger.dev/sdk to 4.5.0 while the CLI is 4.6.3. Even with 4.5.0 installed and resolvable, the dependency list is empty, so trigger deploy passes the required update check.

Recommended fix: Resolve catalog dependencies and retain their protocol metadata separately from the concrete installed version. Use the concrete version for mismatch enforcement. When applying an update, modify the relevant catalog definition or emit actionable guidance instead of replacing the package manifest's catalog reference.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +307 to +322
const isDowngrade = mismatches.some((dep) => {
if (!semver.validRange(dep.version)) {
return false;
}

try {
const depMinVersion = semver.minVersion(dep.version);

if (!depMinVersion) {
return false;
}

return semver.gt(depMinVersion, targetVersion);
} catch {
return false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Unknown protocols remain mismatches

getVersionMismatches avoids the crash but retains every unknown protocol in mismatches. Required checks still abort, while interactive updates replace those specifiers with the CLI version.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@kaiizer777

Copy link
Copy Markdown
Author

Thanks @devin-ai-integration for the thorough review! Both points have been addressed in commit 3a1fe728b:

  1. Concrete Catalog Version Enforcement & Metadata Retention:

    • getTriggerDependencies() now retains rawVersion while attempting resolution of the concrete installed version via tryResolveTriggerPackageVersion(). If resolved (e.g. 4.5.0), the concrete version is used for mismatch detection and downgrade checks, ensuring catalog dependencies don't bypass version enforcement.
    • If resolution fails for an uninstalled/missing package, catalog: dependencies gracefully skip downstream crash-inducing evaluation.
  2. Unknown Protocol Mismatch Filtering:

    • getVersionMismatches() now filters out unknown protocols and non-semver specifiers (!semver.validRange(dep.version) && !semver.valid(dep.version)), preventing unknown protocols from triggering false mismatches in CI or interactive updates.
  3. Manifest Preservation & Actionable Guidance:

    • mutatePackageJsonWithUpdatedPackages() now inspects rawVersion and avoids overwriting "catalog:" specifiers in package.json.
    • Emits actionable guidance warning the user to update their workspace catalog configuration instead of mangling package manifest references.

All 7 Vitest tests are passing, formatted with oxfmt, and validated with oxlint.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: CLI crashes with "Invalid comparator: catalog:" when @trigger.dev/* deps use workspace catalogs (bun/pnpm catalog: protocol)

1 participant