Skip to content

Conversation

DipakHalkude
Copy link

…add guidance on unreachable remote cache

Description

Testing Instructions

@DipakHalkude DipakHalkude requested review from anthonyshew and a team as code owners August 25, 2025 12:58
@turbo-orchestrator turbo-orchestrator bot added area: docs Improvements or additions to documentation needs: triage labels Aug 25, 2025
Copy link
Contributor

vercel bot commented Aug 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
examples-basic-web Ready Ready Preview Comment Aug 25, 2025 1:29pm
examples-designsystem-docs Ready Ready Preview Comment Aug 25, 2025 1:29pm
examples-tailwind-web Ready Ready Preview Comment Aug 25, 2025 1:29pm
examples-vite-web Ready Ready Preview Comment Aug 25, 2025 1:29pm

Copy link
Contributor

vercel bot commented Aug 25, 2025

@DipakHalkude is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@DipakHalkude
Copy link
Author

Adds one-time error when remote cache is unreachable; disables further remote attempts for the run.
Updates caching and run docs to explain behavior and fallback.
Scope limited to turborepo-cache, turborepo-lib docs references.

@@ -155,20 +158,45 @@ impl CacheMultiplexer {

if self.cache_config.remote.read
&& let Some(http) = self.get_http_cache()
&& let Ok(Some((CacheHitMetadata { source, time_saved }, files))) =
Copy link
Contributor

Choose a reason for hiding this comment

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

The put method handles connection errors inconsistently compared to the fetch method - it doesn't disable the HTTP cache or show user-visible error messages for ConnectError and ApiClientError.

View Details
📝 Patch Details
diff --git a/crates/turborepo-cache/src/multiplexer.rs b/crates/turborepo-cache/src/multiplexer.rs
index 46728d980..6fa2a70a8 100644
--- a/crates/turborepo-cache/src/multiplexer.rs
+++ b/crates/turborepo-cache/src/multiplexer.rs
@@ -130,15 +130,33 @@ impl CacheMultiplexer {
         };
 
         match http_result {
-            Some(Err(CacheError::ApiClientError(
-                box turborepo_api_client::Error::CacheDisabled { .. },
-                ..,
-            ))) => {
+            Some(Err(CacheError::ConnectError)) => {
+                if !self.printed_remote_connect_error.swap(true, Ordering::Relaxed) {
+                    error!(
+                        "Cannot access remote cache (connection failed). Falling back to local cache if available."
+                    );
+                }
+                self.should_use_http_cache.store(false, Ordering::Relaxed);
+                Ok(())
+            }
+            Some(Err(CacheError::ApiClientError(box turborepo_api_client::Error::CacheDisabled { .. }, ..))) => {
                 warn!("failed to put to http cache: cache disabled");
                 self.should_use_http_cache.store(false, Ordering::Relaxed);
                 Ok(())
             }
-            Some(Err(e)) => Err(e),
+            Some(Err(CacheError::ApiClientError(..))) => {
+                if !self.printed_remote_connect_error.swap(true, Ordering::Relaxed) {
+                    error!(
+                        "Cannot access remote cache (API error). Falling back to local cache if available."
+                    );
+                }
+                self.should_use_http_cache.store(false, Ordering::Relaxed);
+                Ok(())
+            }
+            Some(Err(other)) => {
+                debug!("failed to put to http cache: {:?}", other);
+                Ok(())
+            }
             None | Some(Ok(())) => Ok(()),
         }
     }

Analysis

The fetch method was updated to handle ConnectError and ApiClientError by disabling the HTTP cache and showing a one-time error message to the user. However, the put method only has special handling for the CacheDisabled variant of ApiClientError, while all other errors (including ConnectError and other ApiClientError variants) are propagated up as failures.

This creates inconsistent behavior:

  • If a connection error occurs during fetch, it's handled gracefully with a user-friendly message and the cache is disabled
  • If the same connection error occurs during put, it causes the entire operation to fail with an error

This inconsistency means that the user experience depends on which operation encounters the connection failure first. For consistency and better user experience, the put method should handle ConnectError and ApiClientError the same way as fetch.


Recommendation

Update the put method's error handling to match the fetch method. Replace the current error handling at lines 132-143 with:

match http_result {
    Some(Err(CacheError::ConnectError)) => {
        if !self.printed_remote_connect_error.swap(true, Ordering::Relaxed) {
            error!(
                "Cannot access remote cache (connection failed). Falling back to local cache if available."
            );
        }
        self.should_use_http_cache.store(false, Ordering::Relaxed);
        Ok(())
    }
    Some(Err(CacheError::ApiClientError(box turborepo_api_client::Error::CacheDisabled { .. }, ..))) => {
        warn!("failed to put to http cache: cache disabled");
        self.should_use_http_cache.store(false, Ordering::Relaxed);
        Ok(())
    }
    Some(Err(CacheError::ApiClientError(..))) => {
        if !self.printed_remote_connect_error.swap(true, Ordering::Relaxed) {
            error!(
                "Cannot access remote cache (API error). Falling back to local cache if available."
            );
        }
        self.should_use_http_cache.store(false, Ordering::Relaxed);
        Ok(())
    }
    Some(Err(other)) => {
        debug!("failed to put to http cache: {:?}", other);
        Ok(())
    }
    None | Some(Ok(())) => Ok(()),
}

Comment on lines +534 to +539
<Callout type="info" title="Remote cache unreachable">
When Remote Cache is configured but unreachable (network error, misconfiguration, or service
outage), Turborepo will print a one-time error early in the run and fall back to local cache if
enabled. This prevents long runs where each workspace silently reports a cache miss.
</Callout>

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<Callout type="info" title="Remote cache unreachable">
When Remote Cache is configured but unreachable (network error, misconfiguration, or service
outage), Turborepo will print a one-time error early in the run and fall back to local cache if
enabled. This prevents long runs where each workspace silently reports a cache miss.
</Callout>

Comment on lines +223 to +232
### Remote cache unreachable

If Remote Caching is configured but cannot be reached (for example due to network errors, incorrect configuration, or the remote service being down), Turborepo now reports a one-time error early in the run:

```text
Cannot access remote cache (connection failed). Falling back to local cache if available.
```

After this, Turborepo disables further remote cache attempts for the current run and continues using the local cache when enabled. This avoids long runs where every workspace silently reports a cache miss.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
### Remote cache unreachable
If Remote Caching is configured but cannot be reached (for example due to network errors, incorrect configuration, or the remote service being down), Turborepo now reports a one-time error early in the run:
```text
Cannot access remote cache (connection failed). Falling back to local cache if available.
```
After this, Turborepo disables further remote cache attempts for the current run and continues using the local cache when enabled. This avoids long runs where every workspace silently reports a cache miss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: docs Improvements or additions to documentation needs: triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants