Google-Health-API / Google-Health-API/google-health-cli
--update-mask always fails with 400: the v4 PATCH request message has no updateMask field
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 253
- Forks
- 27
- PR merge metrics
- No merged PRs in 30d
Description
--update-mask is documented on every writable type's update subcommand, but the v4 API has no such field on the PATCH request message, so passing the flag always fails with a 400.
Reproduction
Straight from the CLI, no custom tooling, on weight (already Writable: true with update support):
$ ghealth data weight create --json '{"weight":{"weightGrams":1234,"notes":"repro - delete me","sampleTime":{"physicalTime":"2026-09-03T18:00:00Z","utcOffset":"-18000s"}}}'
# -> created id 1919002790956405426
$ ghealth data weight update --id 1919002790956405426 \
--json '{"weight":{"weightGrams":4321}}' \
--update-mask weight.weightGrams
{
"error": {
"type": "api",
"code": 1,
"status": 400,
"message": "Invalid JSON payload received. Unknown name \"updateMask\": Cannot bind query parameter. Field 'updateMask' could not be found in request message."
}
}
$ ghealth data weight update --id 1919002790956405426 \
--json '{"weight":{"weightGrams":4321,"sampleTime":{"physicalTime":"2026-09-03T18:00:00Z","utcOffset":"-18000s"}}}'
# -> 200 OK, weightGrams now 4321
Same result with snake_case (?update_mask=...) sent directly to the API, so it isn't a casing mismatch in cmd/data.go:
400 Invalid JSON payload received. Unknown name "update_mask": Cannot bind query parameter.
Test data was deleted afterwards and confirmed gone (404).
Cause
newUpdateCommand in cmd/data.go sets the mask as a query parameter:
if updateMask != "" {
req.Query = url.Values{"updateMask": {updateMask}}
}
The API rejects it because users.dataTypes.dataPoints.patch has no updateMask in its request message — the v4 discovery document lists no query parameters for that method at all. So the flag can only ever turn a working request into a 400.
Suggested fix
Either drop --update-mask, or keep it and fail fast client-side with a clear message rather than sending a request that is guaranteed to 400. Worth a line in the README's write section too, since the current wording implies partial updates are supported — PATCH appears to be whole-object, which matters because a partial body silently drops the fields you leave out.
Happy to send a PR for whichever you prefer.
Environment
ghealthbuilt frommain@ 9cf0274,go build -o ghealth .- go1.26.0 linux/amd64
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in cmd/data.go at newUpdateCommand and reproduce the documented weight update command to confirm the API's 400 response. Check the v4 discovery behavior described in the issue, then implement the chosen handling for --update-mask and update the README write section if applicable; done means the flag no longer sends a guaranteed-invalid request and whole-object PATCH behavior is documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 74/100