The bash launcher's runNativeClient() passed all original CLI args to
sbtn, only stripping --client. This caused sbtn to receive launcher
flags like -mem 10000, which NetworkClient.parseArgs() misclassified:
-mem went to sbtArguments and 10000 went to commandArgs, resulting in
a broken server start command.
**Problem**
Coursier graph.Conflict -> DependencyTree relocation can loop forever when
Maven/Gradle relocation metadata forms a cycle (sbt-site 1.4.1).
**Solution**
Detect relocation cycles with the same step logic as Coursier, skip Conflict
for affected configs, log once per update.
Generated-by: Claude
Fixes unresolved dependency path reporting for Coursier (`ResolveException.failedPaths`) and adds a stable scripted regression.
This PR addresses 5168 by reconstructing unresolved dependency caller chains from the Coursier resolution graph and attaching them to `ResolveException.failedPaths`. That allows unresolved warnings to show the full path from the missing module up to the root project.
It also adds and stabilizes `lm-coursier/unresolved-path` scripted coverage by:
- using a local test Maven repo fixture (no flaky remote test dependency)
- checking update stream output via an sbt task (`checkLog`) instead of shell `grep`
- asserting the unresolved path includes missing module, transitive caller, and root project
Co-authored-by: bitloi <89318445+bitloi@users.noreply.github.com>
**Problem**
When the remote cache server (e.g. bazel-remote using S3 for storage) reports an AC (Action Cache)
hit but the underlying CAS (Content Addressable Storage) blob is missing or
corrupt, ActionCache.cache propagates the resulting exception (typically
java.io.FileNotFoundException) directly to the SBT task engine process with no interception of the propogated error.
This causes a build failure instead of a graceful cache miss.
The three unguarded call sites are:
1. organicTask - syncBlobs after a successful put only caught NoSuchFileException,
missing FileNotFoundException and other IO errors.
2. getWithFailure / readFromSymlink fast-path - syncBlobs inside flatMap with no
exception handling.
3. getWithFailure main branch - both syncBlobs calls and the subsequent IO.read
were completely unguarded.
**Solution**
Guard all three call sites with NonFatal catches:
- Cache read failures (getWithFailure) return Left(None) which the caller
interprets as a cache miss, triggering organic recomputation.
- Cache write failures (organicTask) are demoted to a debug-level log; the task
result that was already computed is returned successfully.
Two regression tests are added to ActionCacheTest:
1. Tests the main getWithFailure branch using the default relative-path converter.
2. Tests the readFromSymlink fast-path using an absolute-path converter so the
symlink created on the first run is found by Files.isSymbolicLink on the second.
Co-authored-by: Idan Ben-Zvi <idanbenzvi@users.noreply.github.com>
Summary
- Fix `SbtParser.importsToLineRanges` to prepend `import` keyword when missing from Dotty's `Import` AST node source spans
- Add unit test for comma-separated import parsing
Co-authored-by: Renzo <170978465+RenzoMXD@users.noreply.github.com>
**Problem**
When the sbt server fails to start (e.g. wrong JDK version), the client
only shows "failed to connect to server" hiding the actual error. The
server stderr is redirected to /dev/null to prevent Linux pipe buffer
deadlocks (#8442), so diagnostic output is lost.
**Solution**
Redirect server stderr to a temp file instead of /dev/null. When the
server fails to start (portfile never appears), read and print the temp
file contents before throwing ServerFailedException. The temp file is
cleaned up eagerly on both success and failure paths.
Fixes#8812
Co-authored-by: Dream <42954461+eureka928@users.noreply.github.com>
**Problem**
Running sbt 2.x with JDK 8 produces a confusing "server was not
detected" error because the JDK version check only required JDK 8+
and only ran in the non-native-client path.
**Solution**
Move java_version detection before the native client decision and add
checkJava17ForSbt2 that requires JDK 17+ when sbt major version >= 2.
Fixes#8813
* [2.x] fix: Fail early when sbt 2.x is run with JDK < 17 (sbtw)
Move JDK version check before native client decision in sbtw and
require JDK 17+ when build.properties declares sbt 2.x.
* [2.x] fix: Fail early when sbt 2.x is run with JDK < 17 (sbt.bat)
Move checkjava before native client decision in sbt.bat and require
JDK 17+ when build.properties declares sbt 2.x.
* [2.x] test: Add minimumJdkVersion helper and unit tests for sbtw
Extract JDK version check logic into Runner.minimumJdkVersion for
testability. Add RunnerSpec with tests for sbt 1.x, 2.x, and 3.x
version detection.
* [2.x] test: Bump fake java to JDK 17 for integration tests
The fake java script used by launcher integration tests reported
JDK 8. Since sbt 2.x now requires JDK 17+, the citest2 (sbt 2.x)
integration tests would fail with the new JDK version check.
* Simulate JDK 9+ rt.jar handling in fake java script
Instead of silently ignoring --rt-ext-dir (which causes sbt.bat
to mkdir on an empty string), properly simulate JDK 9+ behavior
by creating a temp directory with java9-rt-ext- prefix and a
dummy rt.jar inside it.
Co-authored-by: Dream <42954461+eureka928@users.noreply.github.com>
sbt 2.x allows `dependsOn(...)` between subprojects with mismatched
Scala versions without any warning or error. This can lead to confusing
classpath issues at compile or runtime, especially now that Scala 3.8+
has dropped backward TASTy compatibility with 2.13.
Per review feedback, move the Scala version mismatch check from
compileTask to projectDependenciesTask, where PR #8681 already handles
Scala version mixing logic. This provides earlier detection and keeps
the validation co-located with cross-version resolution.
Generated-by: Copilot
Co-authored-by: dev-miro26 <121471669+dev-miro26@users.noreply.github.com>
When using the arguments file (`@argsfile`) mechanism for forked runs,
double quotes inside arguments were not escaped, causing the JVM's
argument file parser to strip them. For example, passing `{"a":1}` as
an argument would result in `{a:1}`.
Escape `"` as `\"` in `createArgumentsFile`, matching the existing
backslash escaping, so the JVM correctly round-trips quoted arguments.
Fixessbt/sbt#7129
Co-authored-by: BrianHotopp <brihoto@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
**Problem**
1. It's difficult to find out when Process fails.
2. global.base setting isn't needed in sbt runner script.
**Solution**
1. Forward to stderr as it happens.
2. Remove global.base setting in the runner script.
Treat explicit plugin toggles as last-call-wins for the same plugin.
This avoids contradictory include/exclude states when disablePlugins(X) is followed by
enablePlugins(X) (and vice versa), aligning behavior with normal override expectations.
Apply the same semantics to ProjectMatrix and add regression coverage:
- unit tests in main/src/test/scala/ProjectSpec.scala
- scripted test in sbt-app/src/sbt-test/project/i1926-disable-enable-plugin
Fixes#4310
Per review, the OOM comes from the version parser - token(StringBasic)
on the right side of || has no examples constraint. Move
.examples(knownVersions*) from the inner number parser to wrap the
entire || expression, so both alternatives are bounded.
When Test / autoScalaLibrary := false, build the non-fork test classloader
without the ScalaInstance layer: use Flat strategy and project classpath
only (rawCP), so tests do not see sbt's scala-library and avoid
NoSuchMethodError / version mismatch (e.g. scala/scala build).
- ClassLoaders.testTask: read autoScalaLibrary; when false use Flat and
rawCP-only fullCP, and do not add si.libraryJars to exclude.
- Add scripted test tests/autoScalaLibrary-test-loader that runs test
with Test / autoScalaLibrary := false.
**Problem**
`testFull` can select an aggregate-only key before a directly defined root key.
In issue #8772 this causes root project tests to be skipped, so a failing root test can pass unexpectedly.
**Solution**
Prefer directly defined keys in `Act.select`, and only fall back to aggregate-only candidates when no direct key exists.
Add scripted regression test `tests/i8772-root-project-testfull` and keep `project/extra-projects-key-aggregate` behavior intact.
Change the behavior when a cached task's output type contains
java.io.File: instead of silently skipping the cache, throw a
compile-time error with a message recommending xsbti.VirtualFileRef,
xsbti.HashedVirtualFileRef, or xsbti.VirtualFile, and linking to the
caching documentation.
Internal sbt tasks that return File types are wrapped with
Def.uncached to opt out of caching.
Fixes https://github.com/sbt/sbt/issues/8762
Generated-by: GitHub Copilot (Claude)
* [2.x] fix: Reject java.io.File as cached task output type
Use @transient on File-returning keys in Keys.scala instead of
wrapping tasks with Def.uncached in Defaults.scala. This ensures
build users who rewire these tasks also get caching skipped
automatically.
- Add @transient to 19 File-returning taskKey definitions in Keys.scala
- Revert Def.uncached wrappers from Defaults.scala
- Error at compile time when File is used as cached task output type
- Update error message to recommend @transient and link to docs
- Update scripted tests to use @transient approach
Fixes#8762
Generated-by: GitHub Copilot (Claude Opus 4.6)
**Problem**
`scalaOrganization` was ignored during compiler bridge resolution because `ZincLmUtil.getDefaultBridgeModule` hard-coded `ScalaArtifacts.Organization` (`org.scala-lang`).
**Solution**
Add a `scalaOrganization` parameter to `ZincLmUtil` methods, and passing `scalaOrganization` value to those methods.
Generated-by: Claude Opus 4.6