Summary
For POST endpoints whose Discovery schema declares a requestBody (not only URL/query parameters), gws serializes every key from --params into the query string and leaves the HTTP body empty. The API then rejects the call.
Version
Repro
Target: people.otherContacts.copyOtherContactToMyContactsGroup — its schema puts copyMask inside requestBody.schema.properties, not parameters.
gws people otherContacts copyOtherContactToMyContactsGroup \
--params '{"resourceName":"otherContacts/<id>","copyMask":"names,phoneNumbers"}' \
--dry-run
Output:
{
"body": null,
"dry_run": true,
"method": "POST",
"query_params": [["copyMask", "names,phoneNumbers"]],
"url": "https://people.googleapis.com/v1/otherContacts/<id>:copyOtherContactToMyContactsGroup"
}
Expected: copyMask should be placed in the JSON request body, not in the query string.
Without --dry-run, the API responds:
{"error":{"code":403,"message":"Request had insufficient authentication scopes.","reason":"unknown"}}
(misleading — the token has both contacts and contacts.other.readonly as the schema requires; the real cause is the missing request body.)
Suggested fix
When constructing the request, split keys in --params between parameters (URL/query) and requestBody.schema.properties (JSON body), based on the Discovery schema for the method. Fields belonging to the request body should be serialized into the body and sent with Content-Type: application/json.
Impact
Any POST method with a request body is currently unusable via --params alone. Examples beyond this one: people.people.createContact, people.people.updateContact, drive.files.copy, and any endpoint where Discovery defines a requestBody schema.
Environment
- OS: Linux (Ubuntu)
- Install:
npm i @googleworkspace/cli local to a project
- Auth: OAuth2 Desktop client, loopback flow, keyring backend
Summary
For POST endpoints whose Discovery schema declares a
requestBody(not only URL/query parameters),gwsserializes every key from--paramsinto the query string and leaves the HTTP body empty. The API then rejects the call.Version
Repro
Target:
people.otherContacts.copyOtherContactToMyContactsGroup— its schema putscopyMaskinsiderequestBody.schema.properties, notparameters.gws people otherContacts copyOtherContactToMyContactsGroup \ --params '{"resourceName":"otherContacts/<id>","copyMask":"names,phoneNumbers"}' \ --dry-runOutput:
{ "body": null, "dry_run": true, "method": "POST", "query_params": [["copyMask", "names,phoneNumbers"]], "url": "https://people.googleapis.com/v1/otherContacts/<id>:copyOtherContactToMyContactsGroup" }Expected:
copyMaskshould be placed in the JSON request body, not in the query string.Without
--dry-run, the API responds:{"error":{"code":403,"message":"Request had insufficient authentication scopes.","reason":"unknown"}}(misleading — the token has both
contactsandcontacts.other.readonlyas the schema requires; the real cause is the missing request body.)Suggested fix
When constructing the request, split keys in
--paramsbetweenparameters(URL/query) andrequestBody.schema.properties(JSON body), based on the Discovery schema for the method. Fields belonging to the request body should be serialized into the body and sent withContent-Type: application/json.Impact
Any POST method with a request body is currently unusable via
--paramsalone. Examples beyond this one:people.people.createContact,people.people.updateContact,drive.files.copy, and any endpoint where Discovery defines arequestBodyschema.Environment
npm i @googleworkspace/clilocal to a project