Skip to content

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

Description

@saiteja007-mv

--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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions