Version
elevenlabs 1.1.0 (npm @elevenlabs/cli@1.1.0), Linux x64.
Summary
GET /v2/voices accepts voice_ids as a repeated query parameter (up to 100). The generated --voice-ids flag is typed as a single string, so there is no way to pass more than one ID through it. The failure is silent: the comma form is accepted, returns 0 voices, and exits 0.
Reproduction
This needs no API key, since --dry-run prints the request without sending it.
$ elevenlabs voices search --voice-ids "AAA,BBB,CCC" --dry-run | jq -c .query_params
[["voice_ids","AAA,BBB,CCC"]]
$ elevenlabs voices search --voice-ids "AAA" --voice-ids "BBB" --dry-run
the argument '--voice-ids <VALUE>' cannot be used multiple times
$ elevenlabs voices search --params '{"voice_ids":["AAA","BBB","CCC"]}' --dry-run | jq -c .query_params
[["voice_ids","AAA"],["voice_ids","BBB"],["voice_ids","CCC"]]
So the request serialiser handles arrays correctly. Only the generated flag cannot express one.
Why the comma form is the dangerous one
Against a real workspace, with two valid IDs and one bogus one:
| Form |
Result |
| repeated flag |
400 validationError (loud, fine) |
--voice-ids "A,B,C" |
{"voices": []}, exit 0 |
--params '{"voice_ids":["A","B","C"]}' |
the two real IDs returned, bogus dropped (correct) |
Controls: a single real ID returns 1, a single bogus ID returns 0. So "absent from the response" legitimately means "this voice does not exist", which makes voice_ids a natural liveness check for a stored set of IDs.
That is exactly what makes the comma form harmful. It is quiet, it exits 0, and it reports every ID as missing. We hold ElevenLabs voice IDs on our own records and use precisely this call to detect voices that have been deleted or re-imported. Had we trusted the documented flag, the audit would have reported the entire set as dead.
Expected
Either accept repetition (--voice-ids A --voice-ids B, i.e. a Vec<String>), or reject the comma form rather than silently joining it. The first is preferable and matches the wire format --params already produces.
Worth checking whether other array-valued query params across the generated surface have the same shape.
Workaround
Use --params '{"voice_ids":[...]}'. Documenting that as the route for array parameters would help in the meantime.
Version
elevenlabs 1.1.0(npm@elevenlabs/cli@1.1.0), Linux x64.Summary
GET /v2/voicesacceptsvoice_idsas a repeated query parameter (up to 100). The generated--voice-idsflag is typed as a single string, so there is no way to pass more than one ID through it. The failure is silent: the comma form is accepted, returns0voices, and exits0.Reproduction
This needs no API key, since
--dry-runprints the request without sending it.So the request serialiser handles arrays correctly. Only the generated flag cannot express one.
Why the comma form is the dangerous one
Against a real workspace, with two valid IDs and one bogus one:
400 validationError(loud, fine)--voice-ids "A,B,C"{"voices": []}, exit0--params '{"voice_ids":["A","B","C"]}'Controls: a single real ID returns 1, a single bogus ID returns 0. So "absent from the response" legitimately means "this voice does not exist", which makes
voice_idsa natural liveness check for a stored set of IDs.That is exactly what makes the comma form harmful. It is quiet, it exits
0, and it reports every ID as missing. We hold ElevenLabs voice IDs on our own records and use precisely this call to detect voices that have been deleted or re-imported. Had we trusted the documented flag, the audit would have reported the entire set as dead.Expected
Either accept repetition (
--voice-ids A --voice-ids B, i.e. aVec<String>), or reject the comma form rather than silently joining it. The first is preferable and matches the wire format--paramsalready produces.Worth checking whether other array-valued query params across the generated surface have the same shape.
Workaround
Use
--params '{"voice_ids":[...]}'. Documenting that as the route for array parameters would help in the meantime.