larksuite/cli · error

Hooks.NewArgs must return *%s

Error message

Hooks.NewArgs must return *%s

What it means

After invoking NewArgs via probeNewArgs, the compiler verifies the returned value is exactly a pointer to the declared ArgsType (reflect.TypeOf(newArgs) == reflect.PointerTo(definition.ArgsType)). A nil result or a different concrete type fails with the expected type name in the message.

Source

Thrown at shortcuts/common/typed_external.go:32

)

// CompileCommandDefinition is the single sealed entry from commandhost into
// the existing shortcut compiler. All authoring fields retain
// extension/command as their owner; the internal token prevents this function
// from becoming a second public compiler API.
func CompileCommandDefinition(definition commandbridge.Definition, _ commandbridge.Access) (Shortcut, error) {
	if definition.ArgsType == nil || definition.DataType == nil {
		return Shortcut{}, fmt.Errorf("ArgsType and DataType are required")
	}
	if definition.Hooks.NewArgs == nil {
		return Shortcut{}, fmt.Errorf("Hooks.NewArgs is required")
	}
	newArgs, err := probeNewArgs(definition.Hooks.NewArgs)
	if err != nil {
		return Shortcut{}, err
	}
	if newArgs == nil || reflect.TypeOf(newArgs) != reflect.PointerTo(definition.ArgsType) {
		return Shortcut{}, fmt.Errorf("Hooks.NewArgs must return *%s", definition.ArgsType)
	}

	output := definition.Output
	if definition.PageOutput {
		output.Meta.Pagination = true
	}
	compiled, err := compileDefinitionParts(
		definition.Metadata,
		definition.Input,
		output,
		definition.ArgsType,
		definition.DataType,
		adaptBridgeHooks(definition.Hooks),
		bridgeRendererMarkers(definition.Hooks.Renderers),
		definition.PageOutput,
	)
	if err != nil {
		return Shortcut{}, err

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Return a pointer to the exact declared args type: func() any { return &MyArgs{} }
  2. Keep ArgsType = reflect.TypeOf(MyArgs{}) and NewArgs returning *MyArgs in sync
  3. If NewArgs can return nil, fix the constructor — nil is always rejected

Example fix

// before
NewArgs: func() any { return MyArgs{} },
// after
NewArgs: func() any { return &MyArgs{} },
Defensive patterns

Strategy: type-guard

Validate before calling

v := definition.Hooks.NewArgs()
if v == nil || reflect.TypeOf(v) != reflect.PointerTo(definition.ArgsType) { return errors.New("NewArgs return type mismatch") }

Type guard

func newArgsMatches(d commandbridge.Definition) bool {
    v, err := probeSafe(d.Hooks.NewArgs)
    return err == nil && v != nil && reflect.TypeOf(v) == reflect.PointerTo(d.ArgsType)
}

Try / catch

sc, err := common.CompileCommandDefinition(def, access)
if err != nil {
    return fmt.Errorf("compile %s: %w", def.Metadata.Command, err)
}

Prevention

When it happens

Trigger: NewArgs returns a value type instead of a pointer (return MyArgs{} instead of &MyArgs{}); NewArgs returns a different struct's pointer than ArgsType declares; NewArgs returns nil; mismatch after changing ArgsType without updating the hook.

Common situations: Refactoring the args struct name/type in one place only; copy-pasting NewArgs from another command with different args; generics or interface wrappers causing the returned reflect type to differ from the declared ArgsType.

Related errors


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