larksuite/cli · error

Hooks.Renderers[%q] is nil

Error message

Hooks.Renderers[%q] is nil

What it means

validateOutputHooks inspects every entry in Hooks.Renderers via a rendererMarker that detects nil values without exposing the private hook type. A map entry whose value is a nil (typed-nil) custom renderer cannot be invoked, so the compiler rejects the definition at startup. Registering a renderer requires a non-nil callable value.

Source

Thrown at shortcuts/common/typed_compile_output.go:21

//nolint:forbidigo // Compiler diagnostics are build-time declaration errors wrapped by the command-set startup guard.
package common

import (
	"fmt"
	"sort"
)

func validateOutputHooks(definition typedOutputDefinition, renderers map[string]rendererMarker) error {
	rendererNames := make([]string, 0, len(renderers))
	for name := range renderers {
		rendererNames = append(rendererNames, name)
	}
	sort.Strings(rendererNames)
	for _, name := range rendererNames {
		renderer := renderers[name]
		if renderer.isNil {
			return fmt.Errorf("Hooks.Renderers[%q] is nil", name)
		}
		if name != "pretty" {
			return fmt.Errorf("Hooks.Renderers[%q] is invalid: custom renderers are only supported for pretty; table, csv, and ndjson use framework formatters", name)
		}
		if definition.Mode == typedOutputFixedJSON {
			return fmt.Errorf("Hooks.Renderers[%q] conflicts with Output.Mode %q: fixed JSON output does not execute custom renderers", name, definition.Mode)
		}
	}
	return nil
}

// rendererMarker lets the bridge compiler inspect nil renderer values without
// exposing the private compiled hook type.
type rendererMarker struct{ isNil bool }

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Assign a real renderer function for the key in Hooks.Renderers.
  2. Delete the map entry if no custom renderer is needed (absence is valid; nil is not).
  3. Check initializer order/conditions that leave the renderer variable nil at compile time.

Example fix

// before
Hooks: common.Hooks{Renderers: map[string]common.Renderer{"pretty": nil}}
// after
Hooks: common.Hooks{Renderers: map[string]common.Renderer{"pretty": func(v any, opts common.RenderOptions) (string, error) { ... }}}
Defensive patterns

Strategy: type-guard

Validate before calling

func checkRenderers(r map[string]common.Renderer) error {
  for name, fn := range r {
    if fn == nil { return fmt.Errorf("renderer %q is nil", name) }
  }
  return nil
}

Type guard

func rendererSet(r map[string]common.Renderer, name string) bool { return r != nil && r[name] != nil }

Prevention

When it happens

Trigger: CompileCommandDefinition (or the typed bridge) called with Hooks.Renderers containing a key mapped to a nil func value, e.g. map[string]any{"pretty": nil} or a typed nil function variable that was never assigned.

Common situations: Declaring the renderer key but forgetting to assign the function; a variable of function type that is nil until some init code runs (and never does); conditional assignment skipped in tests or feature-flagged builds.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/534e3c9db1fb7b48. Report an issue: GitHub.