Skip to content

402. Inspecting a run

github-actions[bot] edited this page Jul 23, 2026 · 1 revision

When Run() returns, the error tells you why the mesh stopped — the run-time report tells you what happened: how many cycles ran, which components activated in each cycle, and with what outcome. This page shows how to read it.


RuntimeInfo

Run() returns (*RuntimeInfo, error). The report is populated even when Run() returns an error.

Field / method Description
Cycles *cycle.Group Ordered history of activation cycles
StartedAt, StoppedAt Wall-clock timestamps
Duration() Total execution time
ri, err := fm.Run()
if err != nil {
    log.Printf("mesh stopped: %v (ran %d cycles in %v)", err, ri.Cycles.Len(), ri.Duration())
}

for _, cyc := range ri.Cycles.All() {
    fmt.Printf("Cycle #%d: %d activations, errors=%v\n",
        cyc.Number(),
        cyc.ActivationResults().Len(),
        cyc.HasActivationErrors(),
    )
}

Two things bound what the history contains:

  • CyclesHistoryLimit (config, default unlimited) caps Cycles to a sliding window of the most recent cycles — older cycles are evicted. Set it for long runs; see Tips & tricks.
  • Idle components are not recorded. A cycle's ActivationResults() only contains results for components that had at least one input signal that cycle. A missing ByName(name) entry means "component had no input that cycle" — treat a nil result the same as not-activated.

Reading a cycle

Each entry in RuntimeInfo.Cycles is a cycle.Cycle:

Method Description
Number() 1-based sequence number
ActivationResults() Per-component results for this cycle
HasActivationErrors() / HasActivationPanics() Status checks
HasActivatedComponents() At least one component activated
AllErrorsCombined() / AllPanicsCombined() Joined errors from all components

RuntimeInfo.Cycles is a group with the same API as signal and port groups (All, First, Last, Find, Filter, ForEach, …) — see Collections and Groups.

Activation results

Each component activation produces an ActivationResult. Query it with ComponentName(), Activated(), Code(), ActivationError(), IsError(), IsPanic(). The per-cycle collection supports ByName, All, Filter, ForEach, Every, Any, Count, and FindAny.

Code Meaning
ActivationCodeOK Success
ActivationCodeNoInput Not activated — no input signals (never recorded in cycle history; you only see it from MaybeActivate, below)
ActivationCodeReturnedError Activation function returned an error
ActivationCodePanicked Panic during activation (recovered with stack trace — a component panic never crashes the mesh)
ActivationCodeWaitingForInputsClear Waiting; inputs were cleared
ActivationCodeWaitingForInputsKeep Waiting; inputs kept for the next cycle
ActivationCodeHookFailed A component hook failed

Helpers: component.IsWaitingForInput(result), component.WantsToKeepInputs(result).

Errors Run() can return

Match with errors.Is:

Error When
ErrReachedMaxAllowedCycles CyclesLimit exceeded
ErrTimeLimitExceeded TimeLimit exceeded
ErrHitAnErrorOrPanic Error/panic with StopOnFirstErrorOrPanic
ErrHitAPanic Panic with StopOnFirstPanic
ErrFailedToDrain Signal draining failed
ErrUnsupportedErrorHandlingStrategy Invalid strategy

Natural completion returns nil.

When is a mesh validated?

You don't need to validate anything yourself:

  • AddComponents rejects invalid components immediately (e.g. missing activation function).
  • Every Run() starts by validating the mesh structure (pipe directions, all pipe destinations belonging to the same mesh) and fails fast with a deterministic error if something is miswired.

Testing a component in isolation

MaybeActivate() runs a single activation outside a full mesh run — handy in unit tests:

_ = myComponent.InputByName("in").PutPayloads(42)
result := myComponent.MaybeActivate()
// result.Code() == component.ActivationCodeOK

Clone this wiki locally