Logo ProcessKit API Reference

ProcessError Type

Structured failure type for ProcessKit operations. Named `ProcessError` (rather than just `Error`) to avoid colliding with the `Result.Error` constructor in F#. Honest-result verbs — `outputString`, `outputBytes`, `exitCode`, `probe` — return their value; only genuine failures surface as a `ProcessError` in the `Result` channel.

Union cases

Union case Description

Adopt(Pid, Detail)

Full Usage: Adopt(Pid, Detail)

Parameters:
    Pid : int
    Detail : string

An external process could not be adopted into a `ProcessGroup` (`ProcessGroup.Adopt`). This is the honest, typed refusal for a *runtime* adoption failure of a specific process — as opposed to `Unsupported`, which reports a mechanism that cannot adopt at all (the POSIX process group, and the FreeBSD process reaper layered over it). The distinguishable causes all live in `Detail`: the target had already exited or its pid does not exist (a TOCTOU race — never a silent success), the caller lacks the rights to place a foreign process into the container, or the process is already assigned to a Job that does not permit nesting on this Windows configuration. `Pid` is the target's pid, or `0` when no live process was associated with the argument.

Pid : int
Detail : string

Cancelled Program

Full Usage: Cancelled Program

Parameters:
    Program : string

The run was cancelled through its `CancellationToken`. A cancellation is always an error. One further producer exists, and it is not a token: a supervision session (`SupervisionSession.StopAsync` / `Supervisor`) whose graceful stop landed before its very first incarnation was ever started ends here, because it has neither a `SupervisionOutcome` to report nor a failure that kept the child from starting — and it will not launch a child just to manufacture one. A stop that lands any later reports the honest result of the incarnation it stopped, or the honest failure of the ones that never started. Code that must tell "my token fired" apart from "I asked for a graceful stop" cannot rely on this case alone; on a session, ask the token (`CancellationToken.IsCancellationRequested`).

Program : string

CassetteMiss Program

Full Usage: CassetteMiss Program

Parameters:
    Program : string

A `RecordReplayRunner` in replay mode found no recorded entry matching the invocation.

Program : string

Exit(Program, Code, Stdout, Stderr)

Full Usage: Exit(Program, Code, Stdout, Stderr)

Parameters:
    Program : string
    Code : int
    Stdout : string
    Stderr : string

A success-requiring verb (`run`) observed a non-zero exit code. `StdoutBytes` (an accessor, not a constructor field — see the note below) carries the exact pre-decode stdout bytes when the checking verb was built over `ProcessResult` (a bytes-based capture — `OutputBytesAsync`/`ProcessResult.ensureSuccess` on a `byte[]` result and their pipeline twins); `None` for a text-based capture (`Stdout` is then the only representation, never reconstructed into bytes). See `ProcessError.StdoutBytes` for the read-without-destructure accessor.

Program : string
Code : int
Stdout : string
Stderr : string

Io Detail

Full Usage: Io Detail

Parameters:
    Detail : string

An underlying I/O failure not attributable to a specific exit.

Detail : string

JsonRpc(Program, Method, Code, Detail, Data)

Full Usage: JsonRpc(Program, Method, Code, Detail, Data)

Parameters:
    Program : string
    Method : string
    Code : int
    Detail : string
    Data : string option

A JSON-RPC peer (`JsonRpcSession`) answered a request with an `error` object instead of a `result` — the protocol's own way of saying "I understood you and I refuse", so it is a failure of that call, never a successful result. `Method` is the request it answers, `Code` and `Detail` are the peer's own `code`/`message` (`-32601` "method not found", `-32602` "invalid params", and the rest of the reserved range are conventional), and `Data` is the raw JSON text of the optional `data` member when the peer attached one. A transport failure of the same call — a truncated frame, the peer's output ending, a timeout — is reported by its own case (`Parse`/`Io`/`Timeout`), never folded in here.

Program : string
Method : string
Code : int
Detail : string
Data : string option

NotFound(Program, Searched)

Full Usage: NotFound(Program, Searched)

Parameters:
    Program : string
    Searched : string option

The program could not be found. `Searched` is the search path that was probed, when known — the whole `PATH` value the lookup walked, `None` when no `PATH` search applied (a path-form program is resolved against its own directory instead). `Message` reports only **how many entries** that path held, not the entries: a `PATH` is an environment value, and a several-thousand-character one has no place in a log line. Read this field when you want to name the directories that were searched.

Program : string
Searched : string option

NotReady(Program, Timeout)

Full Usage: NotReady(Program, Timeout)

Parameters:

A readiness probe (`WaitForLineAsync` / `WaitForPortAsync` / `WaitForSocketAsync` / `WaitForNamedPipeAsync` / `WaitForHttpAsync` / `WaitForPathAsync` / `WaitForAsync`) did not succeed within its timeout.

Program : string
Timeout : TimeSpan

OutputIncomplete Program

Full Usage: OutputIncomplete Program

Parameters:
    Program : string

A checking verb (`Command.RunAsync`/`ParseAsync`/`OutputJsonAsync`, which present their capture **as the whole of stdout**) refused a capture the **bounded post-exit output drain** cut short: the child's exit status was already known, but something that inherited its stdout/stderr — a daemonized worker, a `setsid` helper, a shell's background job — still held the pipe open when the drain's window ran out, so the run closed its own read ends and the capture ends where it was cut (docs/streaming.md, "Output a descendant keeps open"). Deliberately **not** `OutputTooLarge`: nothing exceeded anything here — there need not be a ceiling configured at all — so this case quotes no limit and no line/byte total, and no `OutputBuffer` setting can change the outcome. The lenient capture verbs (`OutputStringAsync`/`OutputBytesAsync`) never produce it: they hand back the partial capture with `ProcessResult.Truncated` set and let the caller decide.

Program : string

OutputTooLarge(Program, LineLimit, ByteLimit, TotalLines, TotalBytes)

Full Usage: OutputTooLarge(Program, LineLimit, ByteLimit, TotalLines, TotalBytes)

Parameters:
    Program : string
    LineLimit : int option
    ByteLimit : int option
    TotalLines : int
    TotalBytes : int

Captured or streamed output exceeded a configured **ceiling**: a fail-loud buffer/stream cap was crossed, or a checking verb refused a capture a bounded buffer had already truncated (`Command.RunAsync`/`ParseAsync`/`OutputJsonAsync` and their pipeline twins — see `ProcessResult.Truncated` for the lenient path). Always about a *volume* against a bound, which is why every wording quotes a unit; a capture cut short with no ceiling in sight — the bounded post-exit output drain's — is its own case (`OutputIncomplete`) rather than a metric-free member of this one. `LineLimit`/`ByteLimit` are the caller's configured ceilings, absent for a channel whose cap is not expressed in that unit (a merged event or protocol-frame stream). Metrics are populated only when their unit applies to that channel (lines, bytes, merged events, or protocol frames) AND the producer actually counted it: a `0` total means "not reported here", never a measured zero, and `Message` quotes only the totals that were populated.

Program : string
LineLimit : int option
ByteLimit : int option
TotalLines : int
TotalBytes : int

Parse(Program, Detail)

Full Usage: Parse(Program, Detail)

Parameters:
    Program : string
    Detail : string

Parsing the captured output into a typed value failed.

Program : string
Detail : string

ResourceLimit Detail

Full Usage: ResourceLimit Detail

Parameters:
    Detail : string

A `ResourceLimits` cap was requested but could not be enforced — the platform has no whole-tree limit primitive (macOS / the Linux process-group fallback), its whole-tree mechanism keeps no accounting a cap could be enforced from (the FreeBSD `procctl(2)` process reaper), or the Linux cgroup v2 controllers could not be enabled (this process is not at the real cgroup root).

Detail : string

RetryPredicate(Program, Original, Detail)

Full Usage: RetryPredicate(Program, Original, Detail)

Parameters:

The retry predicate threw while classifying a failed attempt. `Original` is the typed failure from that attempt; this error is terminal and is never itself eligible for another retry. A C# caller can pass `null` to the generated factory; in that case `Message` reports the original as unavailable and recursive accessors return `None` rather than throwing.

Program : string
Original : ProcessError
Detail : string

Signalled(Program, Signal, Stdout, Stderr)

Full Usage: Signalled(Program, Signal, Stdout, Stderr)

Parameters:
    Program : string
    Signal : int option
    Stdout : string
    Stderr : string

The process was terminated by a signal (Unix) or otherwise killed without a code. `StdoutBytes` is the exact pre-decode capture for a bytes-based checking verb, `None` for a text-based one — see `Exit.StdoutBytes` above.

Program : string
Signal : int option
Stdout : string
Stderr : string

Spawn(Program, Detail)

Full Usage: Spawn(Program, Detail)

Parameters:
    Program : string
    Detail : string

The process could not be spawned (a failure before or during launch).

Program : string
Detail : string

Stdin(Program, Detail)

Full Usage: Stdin(Program, Detail)

Parameters:
    Program : string
    Detail : string

The child's stdin source could not be read (e.g. a missing `FromFile` path) on an otherwise- successful run. A routine broken pipe — the child closed stdin early — is never reported here.

Program : string
Detail : string

Timeout(Program, Timeout, Stdout, Stderr)

Full Usage: Timeout(Program, Timeout, Stdout, Stderr)

Parameters:
    Program : string
    Timeout : TimeSpan
    Stdout : string
    Stderr : string

The run exceeded its configured timeout. `StdoutBytes` is the exact pre-decode capture for a bytes-based checking verb, `None` for a text-based one — see `Exit.StdoutBytes` above.

Program : string
Timeout : TimeSpan
Stdout : string
Stderr : string

Unobserved(Program, Detail)

Full Usage: Unobserved(Program, Detail)

Parameters:
    Program : string
    Detail : string

The run's actual exit status was never observed (see `Outcome.Unobserved`) — a native API failure, an unresolved POSIX reap race, or a hard-killed tree that was not reaped inside the bounded post-kill window, where the process may still be alive and a background reaper holds the remaining wait. `Detail` carries the reason. Always a failure; never fabricated as a clean exit.

Program : string
Detail : string

Unsupported Operation

Full Usage: Unsupported Operation

Parameters:
    Operation : string

The requested operation is unsupported on this platform or in this configuration.

Operation : string

Instance members

Instance member Description

this.Code

Full Usage: this.Code

Returns: int option

The exit code when the error is an `Exit`, or when its `RetryPredicate` original is an `Exit`; `None` otherwise (a signal kill or timeout has none).

Returns: int option

this.Combined

Full Usage: this.Combined

Returns: string option

The captured stdout and stderr joined (stdout, then stderr on a new line when both are non-empty) for the stream-carrying cases (`Exit` / `Signalled` / `Timeout`, or the original attempt inside `RetryPredicate`); `None` otherwise.

Returns: string option

this.IsAdopt

Full Usage: this.IsAdopt

Returns: bool
Returns: bool

this.IsCancelled

Full Usage: this.IsCancelled

Returns: bool
Returns: bool

this.IsCassetteMiss

Full Usage: this.IsCassetteMiss

Returns: bool
Returns: bool

this.IsExit

Full Usage: this.IsExit

Returns: bool
Returns: bool

this.IsIo

Full Usage: this.IsIo

Returns: bool
Returns: bool

this.IsJsonRpc

Full Usage: this.IsJsonRpc

Returns: bool
Returns: bool

this.IsNotFound

Full Usage: this.IsNotFound

Returns: bool
Returns: bool

this.IsNotReady

Full Usage: this.IsNotReady

Returns: bool
Returns: bool

this.IsOutputIncomplete

Full Usage: this.IsOutputIncomplete

Returns: bool
Returns: bool

this.IsOutputTooLarge

Full Usage: this.IsOutputTooLarge

Returns: bool
Returns: bool

this.IsParse

Full Usage: this.IsParse

Returns: bool
Returns: bool

this.IsResourceLimit

Full Usage: this.IsResourceLimit

Returns: bool
Returns: bool

this.IsRetryPredicate

Full Usage: this.IsRetryPredicate

Returns: bool
Returns: bool

this.IsSignalled

Full Usage: this.IsSignalled

Returns: bool
Returns: bool

this.IsSpawn

Full Usage: this.IsSpawn

Returns: bool
Returns: bool

this.IsStdin

Full Usage: this.IsStdin

Returns: bool
Returns: bool

this.IsTimeout

Full Usage: this.IsTimeout

Returns: bool
Returns: bool

this.IsTransient

Full Usage: this.IsTransient

Returns: bool

True for errors that may succeed on a retry (a spawn race or transient I/O). The instance form of `ProcessError.isTransient`, so it reads cleanly from C# as `err.IsTransient` (the not-found classifier already has the generated `err.IsNotFound` tester).

Returns: bool

this.IsUnobserved

Full Usage: this.IsUnobserved

Returns: bool
Returns: bool

this.IsUnsupported

Full Usage: this.IsUnsupported

Returns: bool
Returns: bool

this.Message

Full Usage: this.Message

Returns: string

A short, human-readable description for logs and diagnostics — always **one line**, and always bounded. Every fragment this render embeds that ProcessKit did not author — the program name, a captured stream, a detail, a peer's method name — goes through `MessageText`: terminal and bidirectional-formatting controls, `CR`/`LF`, and the Unicode line/paragraph separators become `U+FFFD` (an ordinary TAB is kept), and anything past 512 characters per fragment is cut with a trailing `…`. So a hostile child, a JSON-RPC peer, or a caller's own parser cannot repaint an operator's terminal, forge extra log lines, or flood the log through this string — and a message stays the same small size whether the child wrote 20 bytes of stderr or 100 KB. A stream-carrying failure (`Exit`/`Signalled`/`Timeout`) quotes at most the **last non-blank line of `Stderr`**, never the whole stream. A `NotFound` reports how many entries the `PATH` it searched held, never the `PATH` itself — an environment value stays out of the message (read `Searched` for it). This is the *render* only. `Detail`, `Stdout`, `Stderr`, `Data`, `Original` and their accessors still carry the full, unmodified text — read them when you need the whole thing.

Returns: string

this.Program

Full Usage: this.Program

Returns: string option

The program the error is about, when it carries one — `None` for `Adopt` (which carries a pid rather than a program) / `ResourceLimit` / `Io` / `Unsupported`, which are not tied to a specific program.

Returns: string option

this.Signal

Full Usage: this.Signal

Returns: int option

The terminating signal number when the error is a `Signalled` with a known number, or when its `RetryPredicate` original is one; `None` otherwise.

Returns: int option

this.Stderr

Full Usage: this.Stderr

Returns: string option

The captured stderr when the error carries it (`Exit` / `Signalled` / `Timeout`, or the original attempt inside `RetryPredicate`); `None` otherwise.

Returns: string option

this.Stdout

Full Usage: this.Stdout

Returns: string option

The captured stdout when the error carries it (`Exit` / `Signalled` / `Timeout`, or the original attempt inside `RetryPredicate`); `None` otherwise.

Returns: string option

this.StdoutBytes

Full Usage: this.StdoutBytes

Returns: byte[] option

The exact pre-decode stdout bytes when the error carries them — the checking verb was built over `ProcessResult` (a bytes-based capture), so the raw bytes survive alongside the lossy, already-decoded `Stdout` text (`Exit` / `Signalled` / `Timeout`, or the original attempt inside `RetryPredicate`). `None` when the capture was text-based (`ProcessResult`): the bytes are never reconstructed from the decoded string — that would fabricate data, not report exact bytes — and `None` for every other case, which carries no stdout at all. Backed by the `stdoutBytesTable` side channel (see `ProcessError.AttachStdoutBytes` above), not a case field: `ProcessResult.FailureError` is the only place that ever attaches an entry, so a directly-constructed `Exit`/`Signalled`/`Timeout` (via `ProcessError.NewExit` and friends, or a pattern-match reconstruction) always reads `None` here until attached.

Returns: byte[] option

Type something to start searching.