secondlife / secondlife/viewer
object.content.save returns `-32603 Internal error: stoi` instead of diagnostics when LSL fails to compile
- Dominant language
- C++
- Stars
- 299
- Forks
- 146
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 88
Description
Environment
Second Life Release 26.4.0.33661928315, Linux x86_64
Description
Summary
Saving syntactically invalid LSL through the script-editor JSON-RPC server
returns a JSON-RPC internal error rather than the documented
{compiled: false, diagnostics: [...]} response. The client is told the request
failed, but not that the script failed to compile, and never receives the
error location or message.
Valid source saves correctly, so the save path itself works. Only the
compile-error path fails.
Environment
- Viewer: Second Life Release 26.4.0.33661928315, Linux x86_64
- Script editor server started via Tools > Script Editor Server (port 9020)
- Client: a JSON-RPC client of our own, which completes
session.handshake
(challenge echoed) and receivessession.oknormally
Reproduction steps
Steps to Reproduce
- Rez a prim you own on a parcel where scripts are enabled.
object.requeston it (publishes; returnssuccess: true).object.item.createwith{prim_id, name, type: "script", vm: "mono"}— returns the new item with itsitem_id.object.content.savewith{prim_id, item_id, content}wherecontentis
syntactically invalid LSL.
Observed
{"jsonrpc": "2.0", "id": 106,
"error": {"code": -32603, "message": "Internal error: stoi"}}
Expected
Per the protocol documentation and the unified_diagnostics feature advertised
in the handshake:
{"compiled": false,
"diagnostics": [{"row": 5, "column": 21, "level": "error", "message": "..."}]}
Reproduces across all five error classes we tried
Each of these, saved alone, produces the identical stoi error:
// 1. missing semicolon
default { state_entry() { llSay(0, "x") } }
// 2. undeclared variable
default { state_entry() { integer n = zzz; } }
// 3. unknown function
default { state_entry() { llNotARealFunction(); } }
// 4. unclosed brace
default { state_entry() { llSay(0, "x");
// 5. two errors at once
default
{
state_entry()
{
integer n = notAThing + 1;
llSay(0, "no semicolon after this")
}
}
Positive control
The same call with valid source succeeds every time:
{"compiled": true, "success": true,
"item_id": "...", "prim_id": "..."}
and the script's state_entry output appears in local chat, confirming the new
source really did compile and run. So the failure is specific to the
compile-error path, not to the save request, the params, or the connection.
Variables ruled out
- Parcel: reproduces on a scripts-disabled parcel and a scripts-enabled one.
- Locale: our first runs logged
Failed to set locale en_US.utf826,600
times (an FHS container with onlyC/POSIXavailable). Re-running with
LANG=Cproduced zero locale warnings and the identicalstoierror, so
locale is not involved. - Upload path: the viewer log shows the invalid source uploading normally
(Uploading: Type: lsltext, UUID: ...) before the error is returned, so the
asset reaches the simulator and the failure is on the way back.
Possibly relevant
indra/newview/llscripteditorws.cpp parses the compile error location with:
static const boost::regex LSL_LOCATION_PATTERN(R"(\((\d+), (\d+)\) : ([^:]+) : (.+))");
...
diagnostic["row"] = std::stoi(match[1].str()) + 1;
diagnostic["column"] = std::stoi(match[2].str()) + 1;
Those stoi calls in saveScript appear to have been added by ece8b732
("Extract the correct compile error location from message.", 2026-08-19);
before that commit this path emitted row = 0, column = 0 and called stoi at
all.
We have not confirmed which line throws. The \d+ capture groups suggest a
successful regex_match should make stoi safe, so the interesting question is
probably which compiler error format fails to match LSL_LOCATION_PATTERN — the
five samples above should make that identifiable. We are reporting the
reproduction rather than a diagnosis.
Impact
This is the compile-feedback path for any external editor using this protocol,
including the official VS Code extension. An editor cannot show compile errors,
and cannot distinguish "your script has a syntax error" from "the connection
broke" — both arrive as the same internal error.
Related
Possibly the same area as #6189 (two divergent compile-feedback paths,
sendCompileResults vs handleObjectContentSave) and #6180
(object.content.save behaviour when running is omitted).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.