{"record":{"id":"ceae1044e427c748","repo":"louthy/language-ext","slug":"closed","errorCode":null,"errorMessage":"closed","messagePattern":"closed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Streaming/Pipes/PipeT/PipeT.DSL.cs","lineNumber":279,"sourceCode":"        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        new PipeTYield<IN1, OUT, M, A>(Value, _ => Next(default).ReplaceAwait(producer));\n    \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        consumer(Value).Bind(_ => Next(default).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        new PipeTYield<IN1, OUT, M, A>(Value, _ => Next(default).PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        consumer(Value).PairEachAwaitWithYield(_ => Next(default));\n\n    internal override K<M, A> Run() => \n        throw new InvalidOperationException(\"closed\");\n}\n\nrecord PipeTAwait<IN, OUT, M, A>(Func<IN, PipeT<IN, OUT, M, A>> Await) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => ","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Streaming/Pipes/PipeT/PipeT.DSL.cs#L261-L297","documentation":"PipeTYield is an intermediate node of the PipeT composition tree: it holds a value that still needs to be paired with a consumer/producer and reduced to a runnable K<M, A>. Its Run() is intentionally unimplemented and throws InvalidOperationException(\"closed\"). The library throws it when you call Run() (directly or via an API like PipeT.run) on a pipe value that is still in the 'yield' state rather than a fully interpreted pipe, i.e. the pipe has already been consumed/closed into a terminal form but is being evaluated as a stream program.","triggerScenarios":"Calling .Run() on a PipeTYield<IN, OUT, M, A> — e.g. invoking PipeT.run / Run on the result of a `yield` step (or a Bind/Map chain ending in a yield) instead of driving the pipe through a producer with the interpreter (PipeT.run with producer/consumer, e.g. via Producer/Consumer/Pipe run helpers).","commonSituations":"Treating PipeT like a monad you can 'execute' after composing yields; misusing an intermediate value from Bind continuation; refactoring code from older LanguageExt Pipes (Pipe) to the new PipeT streaming API where run was implicit; writing custom interpreters that fall through to the default Run() on yield nodes.","solutions":["Drive the pipe through the intended interpreter instead of Run(): use the Producer/Consumer/Pipe run entry points (e.g. Producer.run, Consumer.run, or PipeT combinators that supply a producer for awaits) so every await/yield is paired before evaluation.","If you just have a final value, use PipeT.pure or ensure the composition ends in PipeTPure; a pipe that ends in a yield has no meaning without a consumer.","When writing a custom fold/interpreter over PipeT, handle the PipeTYield case explicitly instead of delegating to Run().","Check LanguageExt version: PipeT (LanguageExt.Streaming) is a new API; consult its samples for the correct run pattern rather than calling internal Run()."],"exampleFix":"// before\nvar pipe = from u in PipeT.yield<IN, OUT, M>(value) select u;\nvar result = pipe.Run(); // throws InvalidOperationException(\"closed\")\n\n// after\nvar result = Producer.run(source, pipe.Map(_ => done)); // interpret the pipe against a real producer/consumer","handlingStrategy":"validation","validationCode":"// Ensure the pipe is interpreted via the producer/consumer runners, never .Run():\n// if you hold a PipeT that came from yield/bind, hand it to Producer.run / Consumer.run.\nvar interpreted = Producer.run(source, pipe); // instead of pipe.Run()","typeGuard":"static bool IsRunnable<A>(K<PipeT<IN, OUT, M>, A> p) =>\n    p is not PipeTYield<IN, OUT, M, A> and not PipeTAwait<IN, OUT, M, A>;","tryCatchPattern":"try { result = Producer.run(source, pipe); }\ncatch (InvalidOperationException e) when (e.Message == \"closed\")\n{\n    // pipe was run in an unpaired (yield) state; rebuild with a producer/consumer\n}","preventionTips":["Never call the internal Run() on PipeT values; always use the public producer/consumer/pipe run helpers.","Treat pipes ending in yield as incomplete programs; bind them to a pure terminal value.","When writing custom folds over PipeT, exhaustively match all record cases (Empty, Pure, Fail, Yield, Await, YieldAll, ...).","Add a unit test that runs every composed pipe through the intended interpreter."],"tags":["csharp","languageext","pipes","streaming","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}