{"record":{"id":"45cb20b9d010bc30","repo":"wavetermdev/waveterm","slug":"must-provide-a-builderid-to-stopbuildercommand","errorCode":null,"errorMessage":"must provide a builderId to StopBuilderCommand","messagePattern":"must provide a builderId to StopBuilderCommand","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshserver/wshserver.go","lineNumber":1155,"sourceCode":"func (ws *WshServer) StartBuilderCommand(ctx context.Context, data wshrpc.CommandStartBuilderData) error {\n\tif data.BuilderId == \"\" {\n\t\treturn fmt.Errorf(\"must provide a builderId to StartBuilderCommand\")\n\t}\n\tbc := buildercontroller.GetOrCreateController(data.BuilderId)\n\trtInfo := wstore.GetRTInfo(waveobj.MakeORef(\"builder\", data.BuilderId))\n\tif rtInfo == nil {\n\t\treturn fmt.Errorf(\"builder rtinfo not found for builderid: %s\", data.BuilderId)\n\t}\n\tappId := rtInfo.BuilderAppId\n\tif appId == \"\" {\n\t\treturn fmt.Errorf(\"builder appid not set for builderid: %s\", data.BuilderId)\n\t}\n\treturn bc.Start(ctx, appId, rtInfo.BuilderEnv)\n}\n\nfunc (ws *WshServer) StopBuilderCommand(ctx context.Context, builderId string) error {\n\tif builderId == \"\" {\n\t\treturn fmt.Errorf(\"must provide a builderId to StopBuilderCommand\")\n\t}\n\tbc := buildercontroller.GetController(builderId)\n\tif bc == nil {\n\t\treturn nil\n\t}\n\treturn bc.Stop()\n}\n\nfunc (ws *WshServer) RestartBuilderAndWaitCommand(ctx context.Context, data wshrpc.CommandRestartBuilderAndWaitData) (*wshrpc.RestartBuilderAndWaitResult, error) {\n\tif data.BuilderId == \"\" {\n\t\treturn nil, fmt.Errorf(\"must provide a builderId to RestartBuilderAndWaitCommand\")\n\t}\n\n\tbc := buildercontroller.GetOrCreateController(data.BuilderId)\n\trtInfo := wstore.GetRTInfo(waveobj.MakeORef(\"builder\", data.BuilderId))\n\tif rtInfo == nil {\n\t\treturn nil, fmt.Errorf(\"builder rtinfo not found for builderid: %s\", data.BuilderId)\n\t}","sourceCodeStart":1137,"sourceCodeEnd":1173,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshserver/wshserver.go#L1137-L1173","documentation":"StopBuilderCommand stops a running builder controller and requires a non-empty builderId. With an empty id the server cannot identify a controller, so it rejects the call before calling buildercontroller.GetController.","triggerScenarios":"Calling StopBuilderCommand RPC with builderId == \"\" — unset variable in the caller, or an empty selection in the UI passed straight through.","commonSituations":"Stop-all handlers iterating a partially loaded builder list; teardown scripts with blank ids; copy-pasted RPC calls where the argument was dropped.","solutions":["Pass the actual builder id to StopBuilderCommand","Skip no-op stops client-side when the id is empty","Verify the id source (UI selection, list entry) is populated"],"exampleFix":"// before\nclient.StopBuilderCommand(ctx, \"\")\n// after\nif builderId != \"\" {\n    client.StopBuilderCommand(ctx, builderId)\n}","handlingStrategy":"validation","validationCode":"if builderId == \"\" {\n    return nil // nothing to stop\n}\nerr := client.StopBuilderCommand(ctx, builderId)","typeGuard":"func isNonEmpty(s string) bool { return s != \"\" }","tryCatchPattern":"if err := client.StopBuilderCommand(ctx, builderId); err != nil {\n    if strings.Contains(err.Error(), \"must provide a builderId\") {\n        return nil // treat as no-op\n    }\n    return err\n}","preventionTips":["Short-circuit stop calls with empty ids on the client","Disable stop buttons until a running builder is selected","Assert ids non-empty in shared RPC helper wrappers"],"tags":["rpc","validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}