wavetermdev/waveterm · error

must provide a builderId to RestartBuilderAndWaitCommand

Error message

must provide a builderId to RestartBuilderAndWaitCommand

What it means

RestartBuilderAndWaitCommand restarts a builder and blocks until the build finishes; it needs data.BuilderId to identify the controller. The server returns this error when BuilderId is empty, before creating/looking up the controller.

Source

Thrown at pkg/wshrpc/wshserver/wshserver.go:1166

		return fmt.Errorf("builder appid not set for builderid: %s", data.BuilderId)
	}
	return bc.Start(ctx, appId, rtInfo.BuilderEnv)
}

func (ws *WshServer) StopBuilderCommand(ctx context.Context, builderId string) error {
	if builderId == "" {
		return fmt.Errorf("must provide a builderId to StopBuilderCommand")
	}
	bc := buildercontroller.GetController(builderId)
	if bc == nil {
		return nil
	}
	return bc.Stop()
}

func (ws *WshServer) RestartBuilderAndWaitCommand(ctx context.Context, data wshrpc.CommandRestartBuilderAndWaitData) (*wshrpc.RestartBuilderAndWaitResult, error) {
	if data.BuilderId == "" {
		return nil, fmt.Errorf("must provide a builderId to RestartBuilderAndWaitCommand")
	}

	bc := buildercontroller.GetOrCreateController(data.BuilderId)
	rtInfo := wstore.GetRTInfo(waveobj.MakeORef("builder", data.BuilderId))
	if rtInfo == nil {
		return nil, fmt.Errorf("builder rtinfo not found for builderid: %s", data.BuilderId)
	}

	appId := rtInfo.BuilderAppId
	if appId == "" {
		return nil, fmt.Errorf("builder appid not set for builderid: %s", data.BuilderId)
	}

	result, err := bc.RestartAndWaitForBuild(ctx, appId, rtInfo.BuilderEnv)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Populate CommandRestartBuilderAndWaitData.BuilderId with the builder's OID before calling
  2. Ensure the builder selection/loading completed before restarting
  3. Add client-side empty-check validation before the RPC

Example fix

// before
client.RestartBuilderAndWaitCommand(ctx, wshrpc.CommandRestartBuilderAndWaitData{})
// after
client.RestartBuilderAndWaitCommand(ctx, wshrpc.CommandRestartBuilderAndWaitData{BuilderId: builderId})
Defensive patterns

Strategy: validation

Validate before calling

if data.BuilderId == "" {
    return fmt.Errorf("cannot restart builder: BuilderId is empty")
}
result, err := client.RestartBuilderAndWaitCommand(ctx, data)

Type guard

func restartable(data wshrpc.CommandRestartBuilderAndWaitData) bool {
    return data.BuilderId != ""
}

Try / catch

result, err := client.RestartBuilderAndWaitCommand(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "must provide a builderId") {
        // caller bug: set BuilderId and retry once
    }
    return nil, err
}

Prevention

When it happens

Trigger: Invoking the RPC with CommandRestartBuilderAndWaitData.BuilderId == "" — the caller never populated it or derived it from an empty state object.

Common situations: Automation pipelines restarting builds after a deploy where the id variable was never assigned; UI restart buttons firing without a selected builder; serialization dropping the field in a custom client.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/c9922eeeee1c88da. Report an issue: GitHub.