geektutu/7days-golang · error

number of options is more than 1

Error message

number of options is more than 1

What it means

parseOptions (day5-http-debug) enforces that the variadic options argument to the dial functions contains at most one *Option. Passing more than one makes the intent ambiguous, so dialing fails with this error. Passing none (or nil) selects DefaultOption, with MagicNumber forced and empty CodecType defaulted.

Source

Thrown at gee-rpc/day5-http-debug/client.go:203

// and returns its error status.
func (client *Client) Call(ctx context.Context, serviceMethod string, args, reply interface{}) error {
	call := client.Go(serviceMethod, args, reply, make(chan *Call, 1))
	select {
	case <-ctx.Done():
		client.removeCall(call.Seq)
		return errors.New("rpc client: call failed: " + ctx.Err().Error())
	case call := <-call.Done:
		return call.Error
	}
}

func parseOptions(opts ...*Option) (*Option, error) {
	// if opts is nil or pass nil as parameter
	if len(opts) == 0 || opts[0] == nil {
		return DefaultOption, nil
	}
	if len(opts) != 1 {
		return nil, errors.New("number of options is more than 1")
	}
	opt := opts[0]
	opt.MagicNumber = DefaultOption.MagicNumber
	if opt.CodecType == "" {
		opt.CodecType = DefaultOption.CodecType
	}
	return opt, nil
}

func NewClient(conn net.Conn, opt *Option) (*Client, error) {
	f := codec.NewCodecFuncMap[opt.CodecType]
	if f == nil {
		err := fmt.Errorf("invalid codec type %s", opt.CodecType)
		log.Println("rpc client: codec error:", err)
		return nil, err
	}
	// send options with server
	if err := json.NewEncoder(conn).Encode(opt); err != nil {

View on GitHub (pinned to cf36443821)

Solutions

  1. Supply exactly one *Option (or none for defaults) to the dial function
  2. Fold all desired settings into a single Option instance before dialing
  3. Fix wrapper functions to merge rather than append extra options into the variadic call

Example fix

// before
base := geerpc.DefaultOption
custom := &geerpc.Option{CodecType: "json"}
conn, err := geerpc.XDialTimeout("tcp", addr, base, custom)

// after
custom := &geerpc.Option{CodecType: "json"}
conn, err := geerpc.XDialTimeout("tcp", addr, custom)
Defensive patterns

Strategy: validation

Validate before calling

if len(opts) > 1 {
	return fmt.Errorf("dial accepts at most one option, got %d", len(opts))
}

Try / catch

conn, err := geerpc.Dial("tcp", addr, opt)
if err != nil && strings.Contains(err.Error(), "number of options is more than 1") {
	// merge options into one and redial
}

Prevention

When it happens

Trigger: Dial/DialTimeout/XDialer invoked with two or more *Option arguments, e.g. dialTimeout(network, addr, defaultOpt, customOpt).

Common situations: Refactoring where option fields were split into multiple structs but both are still forwarded; helper wrappers that append their own option on top of the caller's; test code passing both a base and an override option.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/b65fc8a5acb02e0e. Report an issue: GitHub.