Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cli-dev-without-project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---

Running a CLI command like `dev`, `deploy`, `preview`, or `update` before initializing a project no longer crashes with a raw `Cannot find matching package.json` stack trace. The CLI now detects the missing project and points you to `npx trigger.dev@latest init` instead.
28 changes: 25 additions & 3 deletions packages/cli-v3/src/commands/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,35 @@ export async function updateTriggerPackages(

const projectPath = resolve(process.cwd(), dir);

const { packageJson, readonlyPackageJson, packageJsonPath } = await getPackageJson(projectPath);
let packageJsonResult: Awaited<ReturnType<typeof getPackageJson>> | undefined;

try {
packageJsonResult = await getPackageJson(projectPath);
} catch (error) {
// resolvePackageJSON throws when there's no package.json in projectPath or any parent
// directory — usually because the command ran before the project was set up. Don't crash
// with a raw stack trace; fall through to the actionable guidance below.
logger.debug("Failed to resolve package.json for update check", { projectPath, error });
}

if (!packageJsonResult?.packageJson) {
prettyError(
"No package.json found",
`Couldn't find a package.json in ${projectPath} or any parent directory.`,
"Run `npx trigger.dev@latest init` to set up your project, then try again."
);

// When embedded in another command (e.g. `dev`), there's nothing to run without a project,
// so stop here with a clean exit instead of letting the caller fail again downstream.
if (embedded) {
process.exit(1);
}

if (!packageJson) {
log.error("Failed to load package.json. Try to re-run with `-l debug` to see what's going on.");
return false;
}

const { packageJson, readonlyPackageJson, packageJsonPath } = packageJsonResult;

const newCliVersion = await updateCheck();

if (newCliVersion && !cliVersion.startsWith("0.0.0")) {
Expand Down
26 changes: 14 additions & 12 deletions packages/cli-v3/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,9 @@ async function resolveConfig(
overrides?: Partial<TriggerConfig>,
warn = true
): Promise<ResolvedConfig> {
const packageJsonPath = await resolvePackageJSON(cwd);
const tsconfigPath = await safeResolveTsConfig(cwd);
const lockfilePath = await resolveLockfile(cwd);
const workspaceDir = await findWorkspaceDir(cwd);

const workingDir = result.configFile
? dirname(result.configFile)
: packageJsonPath
? dirname(packageJsonPath)
: cwd;

// `trigger.config` is the fallback value set by c12
// `trigger.config` is the fallback value set by c12. Bail out with actionable guidance before
// touching the filesystem: the pkg-types resolvers below throw raw errors when run outside a
// project (e.g. `dev` before `init`), which would mask this message.
const missingConfigFile = !result.configFile || result.configFile === "trigger.config";

if (missingConfigFile) {
Expand All @@ -178,6 +169,17 @@ async function resolveConfig(
);
}

const packageJsonPath = await resolvePackageJSON(cwd);
const tsconfigPath = await safeResolveTsConfig(cwd);
const lockfilePath = await resolveLockfile(cwd);
const workspaceDir = await findWorkspaceDir(cwd);

const workingDir = result.configFile
? dirname(result.configFile)
: packageJsonPath
? dirname(packageJsonPath)
: cwd;

const config =
"config" in result.config ? (result.config.config as TriggerConfig) : result.config;

Expand Down
Loading