'--arg name value' binds a variable whose value is a JSON string, always. Writing 'jq --arg n 5 ".items[:$n]"' fails with 'Start and end indices of an array slice must be numbers', and a comparison such as '.count == $n' is false because a string never equals a number. The error messages point at the expression rather than at the binding, which makes it easy to misdiagnose.
'--argjson name value' parses the value as JSON, so numbers, booleans, null, arrays and objects arrive with their real types. 'jq --argjson n 5' works, as does '--argjson ids [1,2,3]'.
Related bindings: '--slurpfile' reads a file of JSON values into an array variable, '--rawfile' reads a file into a string variable, and '--args' or '--jsonargs' collect trailing command line arguments into the $ARGS.positional array. All of these are far safer than interpolating shell variables into the filter text, which breaks on quotes and is an injection risk when the value is not trusted. Use '$ENV.NAME' or the env object to read environment variables from inside a filter.