Skip to content

Stream.cycle/1 infinite loop on halted enumerable #15343

Closed

Description

@lukaszsamson

Elixir and Erlang/OTP versions

Erlang/OTP 28 [erts-16.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Elixir 1.20.0-rc.4 (46ebf7c) (compiled with Erlang/OTP 28)

Operating system

any

Current behavior

Repro:
Construct a stateful stream resource that yields one element and pass it to cycle

{:ok, agent} = Agent.start_link(fn -> 0 end)

stream =
  Stream.resource(
    fn -> Agent.get_and_update(agent, fn n -> {n, n + 1} end) end,
    fn
      0 -> {[:a], :done}
      _ -> {:halt, :ok}
    end,
    fn _ -> :ok end
  )

task = Task.async(fn -> Stream.cycle(stream) |> Enum.take(3) end)

case Task.yield(task, 2_000) || Task.shutdown(task, :brutal_kill) do
  {:ok, result} -> IO.inspect(result, label: "ok")
  nil -> IO.puts("HANG: Stream.cycle entered an unbounded loop with no progress")
end

Result:

HANG: Stream.cycle entered an unbounded loop with no progress

Expected behavior

ArgumentError

Activity

  1. josevalim commented on May 6, 2026

    @josevalim
    Member

    Closing in favor of the PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions