typelevel / typelevel/fs2

Files[IO].writeAll creates file when it shouldn't

Open
#3,667 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Scala
Stars
2.5k
Forks
636
Avg merge
2d 4h
Merged PRs (30d)
7

Description

fs2 version: "3.12.2"

import cats.effect.IO  
import cats.effect.IOApp  
import fs2.Stream  
import fs2.io.file.Files  
import fs2.io.file.Path  
  
object FilesBugApp extends IOApp.Simple {  
  
  def run: IO[Unit] = {  
    val bytes: Stream[IO, Byte] = Stream.raiseError[IO](new RuntimeException)  
    bytes.through(Files[IO].writeAll(Path("should-not-be-created"))).compile.drain  
  }  
}

I expect the file not to be created. However, the file is created. This bug also breaks the logic of saving the last file in Stream context. Below is a pseudo-scala description of bug:

val last = Files[F].list("directory").compile.toList.map(_.max)
val saveNow = F.now.flatMap(now => Files[F].writeAll(Path(s"$directory/$now"))))

Stream.eval(last).flatMap(read).map(...).through(saveNow).compile.drain

Here, last always equals to saveNow file. However, if one shifts into F context by removing the Stream.eval the code works as expected.

last.flatMap { file =>
  read(file).map(...).through(saveNow).compile.drain
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Files[IO].writeAll entry point and run the supplied FilesBugApp reproducer against fs2 3.12.2. Trace when the output path is opened relative to upstream stream evaluation, then verify that an upstream RuntimeException leaves should-not-be-created absent and that the last-file streaming scenario no longer includes the output file.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
stream-processing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.