@hiroyukik seems to have partially answered your question by pointing out that you have the path wrong and it should be "/metadata/annotations".
You used the JSON Merge Patch strategy in your comment. I don't think you need to find a JSON Patch alternative as you suggested, as the the Javascript Kubernetes client supports JSON Merge Patch.
My understanding is that you just add a header in the options to set the strategy you want, like so:
const options = { "headers": { "Content-type": PatchUtils.PATCH_FORMAT_JSON_MERGE_PATCH } }
See the docs for how to add this to the function call:
https://kubernetes-client.github.io/javascript/classes/corev1api.corev1api-1.html#patchnamespacedserviceaccount
However, if you do really need to use the JSON Patch strategy, you'll need to check whether the service account has annotations first as that strategy has no way of creating and adding a field in a single operation. See this Github comment for an explanation:
https://github.com/kubernetes/kubernetes/issues/90623#issuecomment-621584160
So a complete shell script example using the JSON Patch strategy would look like this:
kubectl get sa default -n somenamespace -o json \
| jq -e '.metadata | has("annotations")' && \
kubectl patch sa default -n somenamespace --type=json \
-p='[{"op": "add", "path": "/metadata/annotations/eks.amazonaws.com~1role-arn", "value": "ueah"}]' || \
kubectl patch sa default -n somenamespace --type=json \
-p='[{"op":"add","path":"/metadata/annotations","value":{}},{"op":"add","path":"/metadata/annotations/eks.amazonaws.com~1role-arn","value": "ueah"}]'