Skip to content

-F doesn't parse JSON object inside an array #8621

Description

@pablonete

Describe the bug

gh version 2.42.1 (2024-01-15)
https://github.com/cli/cli/releases/tag/v2.42.1

For this Custom Properties endpoint, we need to pass a JSON with an array of objects. But neither the -f or the -F options parse that subobject, and it's always sent as a string, which is rejected by the endpoint.

Steps to reproduce the behavior

gh api \
  --method PATCH \
  /repos/properties-game/chess/properties/values \
  -F 'properties[]'='{"property_name": "color", "value": "red"}'

Expected vs actual behavior

Debug:

pablo@MBP-de-Pablo ~ % GH_DEBUG=api gh api \
  -X PATCH \
  /repos/properties-game/chess/properties/values \
  -f 'properties[]'='{"property_name": "color", "value": "red"}'

* Request at 2024-01-25 11:32:44.403733 +0100 CET m=+0.085115404
* Request to https://api.github.com/repos/properties-game/chess/properties/values
> PATCH /repos/properties-game/chess/properties/values HTTP/1.1
> Host: api.github.com
> Accept: */*
> Authorization: token ████████████████████
> Content-Length: 69
> Content-Type: application/json; charset=utf-8
> Time-Zone: Europe/Madrid
> User-Agent: GitHub CLI 2.42.1

{
  "properties": [
    "{\"property_name\": \"color\", \"value\": \"red\"}"
  ]
}

< HTTP/2.0 422 Unprocessable Entity
[Redacted]
* Request took 392.360715ms
{
  "message": "Invalid request.\n\nInvalid property /properties/0: `\"{\\\"property_name\\\": \\\"color\\\", \\\"value\\\": \\\"red\\\"}\"` is not of type `object`.",
  "documentation_url": "https://docs.github.com/rest/repos/custom-properties#create-or-update-custom-property-values-for-a-repository"
}
gh: Invalid request.

Invalid property /properties/0: `"{\"property_name\": \"color\", \"value\": \"red\"}"` is not of type `object`. (HTTP 422)

In the request body, we'd expect an array of objects:

{
  "properties": [
    { "property_name": "color", "value": "red" }
  ]
}

instead of an array of strings

{
  "properties": [
    "{\"property_name\": \"color\", \"value\": \"red\"}"
  ]
}

Workaround

@williammartin figured out a workaround with --input:

echo '{"properties": [{"property_name": "color", "value": "red"}] }' | GH_DEBUG=api gh api --method PATCH /repos/properties-game/chess/properties/values --input -

although it would still be desirable that -F understand json, as we have the alternative of -f if we want to pass the string unparsed. Today both behave the same for this input.

Activity

  1. added
    gh-apirelating to the gh api command
    enhancementa request to improve CLI
    and removed
    bugSomething isn't working
    on Feb 20, 2024
  2. williammartin commented on Feb 20, 2024

    @williammartin
    Member

    I've relabelled this as an enhancement because I don't believe it's documented anywhere that we would expect this to work. Here are the docs for -F and -f:

      -F, --field key=value       Add a typed parameter in key=value format
      -f, --raw-field key=value   Add a string parameter in key=value format
    

    While we might hope that -F handles json, it doesn't, and that's what this enhancement request is really about.

    I did a naive implementation for -F support in a3ade6b which attempts to unmarshal the field as JSON, but I'm not sure what the pitfalls of this approach are (for example, what is valid json?).

  3. babakks commented on Mar 31, 2024

    @babakks
    Member

    @williammartin These are all valid JSONs: 999, true, false, null, "foo". So, I don't think it's really safe.

    Maybe moving the JSON unmarshal part to the end of the method could help (where the input is not of any other expected type)?

  4. babakks commented on Mar 31, 2024

    @babakks
    Member

    I know it's not that pretty, but can't we just add a new argument, like --json-field, for such cases? This doesn't break CLI compatibility and also provides the desired improvements.

  5. asos-matthewbarber commented on Apr 5, 2024

    @asos-matthewbarber

    I've relabelled this as an enhancement because I don't believe it's documented anywhere that we would expect this to work. Here are the docs for -F and -f:

      -F, --field key=value       Add a typed parameter in key=value format
      -f, --raw-field key=value   Add a string parameter in key=value format
    

    While we might hope that -F handles json, it doesn't, and that's what this enhancement request is really about.

    I did a naive implementation for -F support in a3ade6b which attempts to unmarshal the field as JSON, but I'm not sure what the pitfalls of this approach are (for example, what is valid json?).

    This would be really useful to be documented on the api docs . If you use -F with a bool for the value it fails with the value must be a string or an array. Only after trying -f, found from this issue, did it work.

    Maybe an extra set of properties to update in the example

    -F "properties[][property_name]=is_for_abc" -f "properties[][value]=true"

  6. peter-mccann commented on Dec 10, 2024

    @peter-mccann

    Please open a Documentation Issue against the CLI example here Create or update custom property values for a repository. Knowing that -f/-F would not work would have saved me several hours of time.
    Yes I'm a little stubborn, and could have switched to curl.. but I wanted to stick with a single method.

  7. added
    enhancementa request to improve CLI
    and removed
    enhancementa request to improve CLI
    on Feb 27, 2025
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

    enhancementa request to improve CLIgh-apirelating to the gh api command

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions