bru run: API key auth with placement: queryparams is not sent when the URL or key value contains {{variables}}
Internal - [BRU-4681]
I have checked the following:
- I have searched existing issues and found nothing related to my issue.
This bug is:
- Making Bruno unusable for me.
- Slowing me down but I'm able to continue working.
- Annoying.
- This feature was working in a previous version but is broken in the current release.
Bruno version
CLI 4.2.0
Operating System
Linux
Specific OS Version / Distro
Debian
Describe the bug
With auth:apikey and placement: queryparams, bru run only sends the key when neither the request URL nor the key value contains a variable. That rules out the usual {{baseUrl}}/path + {{apiKey}} setup.
- URL starts with a variable (
{{baseUrl}}/echo): the CLI logsInvalid URL: {{baseUrl}}/echo?a=1 TypeError: Invalid URLand sends the request without the key. It still reports200 OKand✓ PASSwhen there are no assertions, so the failure is easy to miss. - Literal URL but the value is a variable (
value: {{apiKey}}): the key is sent askey=%7B%7BapiKey%7D%7D, the percent-encoded placeholder. The variable is never substituted.
This happens with both collection-level auth (auth: inherit) and request-level auth. placement: header works with variables in both the URL and the value.
The cause is in packages/bruno-cli/src/runner/prepare-request.js. Both the collection-level branch (line 87 in 4.2.0) and the request-level branch (line 343) do:
const urlObj = new URL(request.url);
urlObj.searchParams.set(request.auth.apikey?.key, request.auth.apikey?.value);
axiosRequest.url = urlObj.toString();prepareRequest runs before interpolateVars (run-single-request.js lines 183 and 385). So:
new URL('{{baseUrl}}/…')throws; the error is caught and only logged.searchParams.setpercent-encodes the{{apiKey}}placeholder, and the later interpolation no longer recognizes it.
Adding the query parameter after interpolation would fix both cases.
Related but different: #3492 and #3732 were about API key auth not being applied at all and were fixed in 2.3.0.
Steps to reproduce
- Start an echo server:
node -e 'require("http").createServer((q,r)=>{console.log(q.url);r.end("ok")}).listen(4599)' - Create the collection below.
- Run
bru run --env localin the collection folder. - Compare the URLs the server logs with the expected ones:
| Request | Server received | Expected |
|---|---|---|
1 inherited key, {{baseUrl}} URL |
/echo?a=1 |
/echo?a=1&key=secret123 |
2 request key, {{baseUrl}} URL |
/echo?a=1 |
/echo?a=1&key=secret123 |
3 request key {{apiKey}}, literal URL |
/echo?a=1&key=%7B%7BapiKey%7D%7D |
/echo?a=1&key=secret123 |
| 4 literal key value, literal URL | /echo?a=1&key=secret123 ✅ |
|
5 placement: header, {{baseUrl}} URL |
header x-api-key: secret123 ✅ |
All five requests are reported as 200 OK, and the run as ✓ PASS.
Collection to reproduce
bruno.json
{ "version": "1", "name": "apikey-queryparams-repro", "type": "collection" }collection.bru
auth {
mode: apikey
}
auth:apikey {
key: key
value: {{apiKey}}
placement: queryparams
}environments/local.bru
vars {
baseUrl: http://localhost:4599
apiKey: secret123
}1.bru (inherited key)
meta {
name: 1 inherited key, url with baseUrl
type: http
seq: 1
}
get {
url: {{baseUrl}}/echo?a=1
body: none
auth: inherit
}2.bru (request-level key)
meta {
name: 2 request key, url with baseUrl
type: http
seq: 2
}
get {
url: {{baseUrl}}/echo?a=1
body: none
auth: apikey
}
auth:apikey {
key: key
value: {{apiKey}}
placement: queryparams
}3.bru is the same as 2.bru with url: http://localhost:4599/echo?a=1.
Screenshots/Live demo link
CLI output (stack traces trimmed):
Invalid URL: {{baseUrl}}/echo?a=1 TypeError: Invalid URL
code: 'ERR_INVALID_URL',
input: '{{baseUrl}}/echo?a=1'
1 inherited key, url with baseUrl (200 OK) - 14 ms
Invalid URL: {{baseUrl}}/echo?a=1 TypeError: Invalid URL
2 request key, url with baseUrl (200 OK) - 1 ms
3 request key, literal url (200 OK) - 1 ms
4 request key literal value, literal url (200 OK) - 0 ms
5 header placement, url with baseUrl (200 OK) - 1 ms
│ Status │ ✓ PASS │Server log:
/echo?a=1
/echo?a=1
/echo?a=1&key=%7B%7BapiKey%7D%7D
/echo?a=1&key=secret123
/echo?a=1 x-api-key: secret123Source: usebruno/bruno