Hit this while decoding a JSON payload that contained a "_request_id" field. SnakePickle.snakeToCamel calls x(0) on each segment without checking for empty strings, which throws StringIndexOutOfBoundsException whenever split("_", -1) produces an empty segment — i.e. for any key with leading, trailing, or consecutive underscores.
Reproducer (scala-cli):
//> using scala 3.8.3
@main def repro(): Unit =
// Same logic as core/src/main/scala/sttp/ai/core/json/SnakePickle.scala (lines 13-14)
def snakeToCamel(s: String): String =
val res = s.split("_", -1).map(x => s"${x(0).toUpper}${x.drop(1)}").mkString
s"${s(0).toLower}${res.drop(1)}"
snakeToCamel("_type") // throws
snakeToCamel("some__key") // throws
snakeToCamel("trailing_") // throws
Output:
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
at SnakePickle$.snakeToCamel(SnakePickle.scala:14)
Source pointer:
|
private def snakeToCamel(s: String): String = { |
|
val res = s.split("_", -1).map(x => s"${x(0).toUpper}${x.drop(1)}").mkString |
Any OpenAI-style API field whose JSON name starts with _ (private/internal fields are common) will trigger this. Filtering empty segments — s.split("_", -1).filter(_.nonEmpty) — fixes it without changing behaviour for well-formed keys. There's a related but milder issue in camelToSnake where strings starting with an uppercase letter end up with a leading underscore, but that one isn't a crash. Happy to PR both.
Hit this while decoding a JSON payload that contained a
"_request_id"field.SnakePickle.snakeToCamelcallsx(0)on each segment without checking for empty strings, which throwsStringIndexOutOfBoundsExceptionwheneversplit("_", -1)produces an empty segment — i.e. for any key with leading, trailing, or consecutive underscores.Reproducer (scala-cli):
Output:
Source pointer:
sttp-ai/core/src/main/scala/sttp/ai/core/json/SnakePickle.scala
Lines 13 to 14 in fa739fa
Any OpenAI-style API field whose JSON name starts with
_(private/internal fields are common) will trigger this. Filtering empty segments —s.split("_", -1).filter(_.nonEmpty)— fixes it without changing behaviour for well-formed keys. There's a related but milder issue incamelToSnakewhere strings starting with an uppercase letter end up with a leading underscore, but that one isn't a crash. Happy to PR both.