Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(errors): improve error message for recursive calls #9650

Merged
merged 9 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from 4 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
17 changes: 14 additions & 3 deletions crates/turborepo-lib/src/task_graph/visitor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ mod command;
mod error;
mod exec;
mod output;

use std::{
borrow::Cow,
collections::HashSet,
Expand All @@ -11,6 +10,7 @@ use std::{
};

use console::{Style, StyledObject};
use convert_case::{Case, Casing};
use error::{TaskError, TaskWarning};
use exec::ExecContextFactory;
use futures::{stream::FuturesUnordered, StreamExt};
Expand All @@ -23,6 +23,7 @@ use tracing::{debug, error, warn, Span};
use turbopath::{AbsoluteSystemPath, AnchoredSystemPath};
use turborepo_ci::{Vendor, VendorBehavior};
use turborepo_env::{platform::PlatformEnv, EnvironmentVariableMap};
use turborepo_errors::TURBO_SITE;
use turborepo_repository::package_graph::{PackageGraph, PackageName, ROOT_PKG_NAME};
use turborepo_telemetry::events::{
generic::GenericEventBuilder, task::PackageTaskEventBuilder, EventBuilder, TrackedErrors,
Expand Down Expand Up @@ -77,12 +78,21 @@ pub enum Error {
task_id: TaskId<'static>,
},
#[error(
"root task {task_name} ({command}) looks like it invokes turbo and might cause a loop"
"Your `package.json` script looks like it invokes a Root Task ({task_name}), creating a \
loop of `turbo` invocations. You likely have misconfigured the strategy for your scripts \
anthonyshew marked this conversation as resolved.
Show resolved Hide resolved
and tasks or your package manager's Workspace structure."
)]
#[diagnostic(
code(recursive_turbo_invocations),
url(
"{}/messages/{}",
TURBO_SITE, self.code().unwrap().to_string().to_case(Case::Kebab)
)
)]
RecursiveTurbo {
task_name: String,
command: String,
#[label("task found here")]
#[label("This script calls `turbo`, which calls the script, which calls `turbo`...")]
span: Option<SourceSpan>,
#[source_code]
text: NamedSource,
Expand Down Expand Up @@ -215,6 +225,7 @@ impl<'a> Visitor<'a> {
Some(cmd) if info.package() == ROOT_PKG_NAME && turbo_regex().is_match(cmd) => {
package_task_event.track_error(TrackedErrors::RecursiveError);
let (span, text) = cmd.span_and_text("package.json");

return Err(Error::RecursiveTurbo {
task_name: info.to_string(),
command: cmd.to_string(),
Expand Down
40 changes: 40 additions & 0 deletions docs/repo-docs/messages/recursive-turbo-invocations.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: Recursive `turbo` invocations
description: Learn more about errors with recursive sccripts and tasks in Turborepo.
---

## Why this error occurred

When a cycle of `turbo` invocations is detected in a [single-package workspace](https://turbo.build/repo/docs/guides/single-package-workspaces), Turborepo will error to prevent the recursive calls to itself. Typically, this situation occurs for one of two reasons:

### Recursion in scripts and tasks

In a single-package workspace, a script in `package.json` that calls a Turborepo task with the same name causes a loop.

```json title="./package.json"
{
"scripts": {
"build": "turbo run build"
}
}
```

Calling the `build` script calls `turbo run build`. `turbo run build` then calls the `build` script, initiating the loop of recursive calls.

To resolve this, ensure that the name of the script in `package.json` is not the same as the Turborepo task. For example, to fix the snippet above, renaming the script would break the cycle:

```json title="./package.json"
{
"scripts": {
"build:app": "turbo run build"
}
}
```

### Package manager Workspace misconfiguration

A misconfigured workspace can make it appear that a [multi-package workspace](https://vercel.com/docs/vercel-platform/glossary#multi-package-workspace) is a single-package workspace. This causes Turborepo to infer that the repository is of the wrong type, causing it to see the script in `package.json` to be recursive.

Your repo can end up in this state in a few ways, with the most common being that the [packages are not defined according to your package manager](https://turbo.build/repo/docs/crafting-your-repository/structuring-a-repository#specifying-packages-in-a-monorepo). An npm workspace that is missing the `workspaces` field in `package.json` or a pnpm workspace that is missing a `pnpm-workspace.yaml` file can result in this error message.

Check that your repository is complying with standards for multi-package workspaces and correct any issues.
Loading