ipfs/kubo · error

lcStatStop: stopFunc was nil

Error message

lcStatStop: stopFunc was nil

What it means

This is a defensive invariant inside lcStatStop's OnStop hook: the lcStartStop helper registers a stop callback captured in a closure, and if OnStop fires before the constructor ever assigned stopFunc, the guard returns this error. The code comment notes this should theoretically never happen; it indicates a lifecycle wiring bug in the fx app (stop hook registered before/without the start hook setting the variable).

Source

Thrown at core/node/helpers.go:35

func (lcss *lcStartStop) Append(f func() func()) {
	// Hooks are guaranteed to run in sequence. If a hook fails to start, its
	// OnStop won't be executed.
	var stopFunc func()

	lcss.LC.Append(fx.Hook{
		OnStart: func(ctx context.Context) error {
			if ctx.Err() != nil {
				return nil
			}
			stopFunc = f()
			return nil
		},
		OnStop: func(ctx context.Context) error {
			if ctx.Err() != nil {
				return nil
			}
			if stopFunc == nil { // Theoretically this shouldn't ever happen
				return errors.New("lcStatStop: stopFunc was nil")
			}
			stopFunc()
			return nil
		},
	})
}

func maybeProvide(opt any, enable bool) fx.Option {
	if enable {
		return fx.Provide(opt)
	}
	return fx.Options()
}

// nolint unused
func maybeInvoke(opt any, enable bool) fx.Option {
	if enable {
		return fx.Invoke(opt)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Check for recently changed lifecycle wiring (lc.Append order) in the constructor using this helper — the Start hook must run before Stop can fire
  2. Capture the error in a bug report with the daemon's log level raised (GOLOG_LOG_LEVEL=debug) to see which lifecycle hook sequence triggered it
  3. Upgrade kubo — if this reproduces on an official build it is a bug worth filing at github.com/ipfs/kubo/issues
Defensive patterns

Strategy: try-catch

Try / catch

if err := app.Stop(ctx); err != nil && strings.Contains(err.Error(), "lcStatStop: stopFunc was nil") {
    // lifecycle wiring bug: log and file an issue; safe to retry shutdown
    logger.Errorw("lifecycle stop hook fired without start", "err", err)
}

Prevention

When it happens

Trigger: fx invokes the app's OnStop hook while the stopFunc captured variable is still nil — i.e. the lifecycle hook was appended but the start function that assigns stopFunc never ran or has not yet run (e.g. start failed midway or was skipped, then shutdown proceeds).

Common situations: A resource whose Start step failed silently or whose Append order in fx was changed during a refactor; daemon shutdown racing a partially constructed node. Practically unobservable in healthy runs.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/ef5519632cb3ee0f. Report an issue: GitHub.