"Best before end: 1988"

jq argfile/slurpfile migration

I’ve been using jq --argfile for a few years, despite the manpage up to jq 1.6 advising against it. Let me create a demonstration JSON that resembles my telemetry use case:

$ jq -n '.metric1=1234|.metric2=5678' | tee /tmp/test.json
{
  "metric1": 1234,
  "metric2": 5678
}

This data used to be read via --argfile, bound to a variable and hooked into a bigger JSON object:

$ jq -n --argfile m /tmp/test.json '.metrics=$m'
{
  "metrics": {
    "metric1": 1234,
    "metric2": 5678
  }
}

The Version of jq on Debian 13/Trixie does not support the --argfile option anymore:

jq: Unknown option --argfile

TL;DR: I had to replace --argfile with --slurpfile and use the first list index from the bound variable:

$ jq -n --slurpfile m /tmp/test.json '.metrics=$m[0]'
{
  "metrics": {
    "metric1": 1234,
    "metric2": 5678
  }
}

Why though?

--argfile behaves differently depending on the number of JSON objects in the file. If it the file contains 1 JSON object, it is returned as a JSON object. If I create a JSON file that contains 2 JSON objects, they are converted to a list of objects:

$ jq -n '.metric1=1234,.metric2=5678' | tee /tmp/test2.json 
{
  "metric1": 1234
}
{
  "metric2": 5678
}
$ jq -n --argfile m /tmp/test.json '.metrics=$m'
{
  "metrics": {
    "metric1": 1234,
    "metric2": 5678
  }
}
$ jq -n --argfile m /tmp/test2.json '.metrics=$m'
{
  "metrics": [
    {
      "metric1": 1234
    },
    {
      "metric2": 5678
    }
  ]
}

--slurpfile treats all JSON objects the same and if the file contains a single JSON object, returns a list of JSON objects containing a single entry. Hence the added [0] from the TL;DR section.

One might argue that the removal of --argfile could have come following a clear deprecation notice instead of semi-permanently (first appearance in Debian 9/Stretch) advising against its use and then removing it all of a sudden. However, as far as I am concerned, the issue was detected in earliest Debian 13 compatibility testing within days after the freeze, I immediately knew what was cooking, the migration to --slurpfile was trivial, and it can also be deployed retroactively on all older systems.