larksuite/cli · error

Hooks.Renderers[%q] is invalid: custom renderers are only su

Error message

Hooks.Renderers[%q] is invalid: custom renderers are only supported for pretty; table, csv, and ndjson use framework formatters

What it means

Custom renderers may only be registered under the "pretty" key. The framework owns the table, csv, and ndjson formatters, so registering a renderer with any other name is rejected at compile time to prevent silently shadowing or bypassing framework output formats that the CLI contract guarantees.

Source

Thrown at shortcuts/common/typed_compile_output.go:24

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. Rename the renderer key to "pretty" if a custom human-readable rendering is intended.
  2. Delete the entry and rely on the built-in framework formatter for table/csv/ndjson.
  3. Customize the underlying data (Output.Data shape/overrides) rather than replacing framework formatters.

Example fix

// before
Renderers: map[string]Renderer{"table": renderTable}
// after
Renderers: map[string]Renderer{"pretty": renderPretty}
Defensive patterns

Strategy: validation

Validate before calling

func onlyPrettyRenderers(r map[string]common.Renderer) error {
  for name := range r {
    if name != "pretty" {
      return fmt.Errorf("renderer %q not allowed; only \"pretty\" is customizable", name)
    }
  }
  return nil
}

Prevention

When it happens

Trigger: CompileCommandDefinition with Hooks.Renderers keyed by something other than "pretty", e.g. map[string]Renderer{"table": myTableRenderer} or {"json": ...} or {"csv": ...}.

Common situations: Assuming all output formats are customizable; porting a config where renderers were once keyed by format name; adding a brand-new format name hoping the framework would pick it up.

Related errors


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