Google-Health-API / Google-Health-API/google-health-cli

--update-mask always fails with 400: the v4 PATCH request message has no updateMask field

Open Beginner friendly
#15 0 comments 0 reactions 0 assignees View on GitHub

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
  • ghealth built from main @ 9cf0274, go build -o ghealth .
  • go1.26.0 linux/amd64

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.