Avoid percent-encoding for "(" and ")" characters.#43
Merged
Conversation
7893927 to
256080a
Compare
This was referenced Jul 5, 2026
C0D3-M4513R
requested changes
Jul 5, 2026
The VRChat API does not accept percent-encoded variants of InstanceID, specifically the characters "(" and ")". This causes an error when attempting the following API call:
```
https://api.vrchat.cloud/api/1/instances/wrld_28aab3e4-953f-4c85-9223-ef29a0873a6e:31124%7Egroup%28grp_b2a19685-c53e-4c5a-9503-744a5373bf2c%29%7EgroupAccessType%28plus%29%7Eregion%28use%29/shortName
```
```json
{"error":{"message":"\"malformed url\"","status_code":400,"waf_code":26497}}
```
When using the raw string without encoding, the API yields a `200` response as expected.
```
https://vrchat.com/api/1/instances/wrld_28aab3e4-953f-4c85-9223-ef29a0873a6e:31124~group(grp_b2a19685-c53e-4c5a-9503-744a5373bf2c)~groupAccessType(plus)~region(use)/shortName
```
C0D3-M4513R
approved these changes
Jul 5, 2026
Collaborator
|
Published as |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes URL encoding of
InstanceIDvalues.The Rust SDK follows the application/x-www-form-urlencoded percent-encode set for encoding. However, the VRChat API rejects percent-encoded parentheses (
%28and%29) inInstanceIDpath parameters, returning a400 "malformed url"response instead of accepting the RFC-compliant encoding.For example, the following request fails:
{"error":{"message":"\"malformed url\"","status_code":400,"waf_code":26497}}Using the same
InstanceIDwithout encoding the parentheses succeeds as expected:I initially encountered this issue in the Rust SDK, but it also affects the C# and Java SDK:
To better understand the behavior, I tested every ASCII character in both encoded and unencoded form against multiple API endpoints. The following reserved characters consistently resulted in malformed requests when percent-encoded:
These all fall under
reservedcharacters as defined in RFC3986 and are used for delimeters. The~character, despite my earlier assumption, does not exhibit this behavior when percent-encoded, which is consistent with it being part of the RFC 3986 unreserved character set.The OpenAPI specification disallows the
:/?#[]@!$&'()*+,;=characters from appearing inpath,query,cookieandheaderparameters without encoding by default. It is possible to override this usingallowReserved, but unfortunately that's exlusive to query parameters. The future OpenAPI 3.2 specification allows defining this for all relevant parameters, but it will take a while for it to be adopted.Since modifying OpenAPI Generator itself is undesirable, I considered several alternatives:
type: passwordfor theSchema ObjectThis was my first attempt (See #584), but it's confusing and doesn't appear to be properly supported by generator templates.
This is an easy bandaid solution, but allowing strings to embed delimeters like "#" and "?" to adres any endpoint seems undesirable. The purpose of encoding is to prevent malicious strings from silently embedding delimeters, or developers from accidentally doing it themselves.
This requires the SDKs to fork/patch url encoding functions like
form_urlencoded::byte_serialize(Rust) orUri.EscapeDataString(C#). RFC 3986 permits this behavior when a URI scheme explicitly treats reserved characters as data:This preserves the safety benefits of percent-encoding for all other reserved characters while making the minimal compatibility change required for the VRChat API.
type: stringand combine it withformat: x-vrc-no-encodefor theSchema Objectto conditionally skip encoding.This would allow overriding the templates, by disabling percent-encoding in the mustache template if
dataFormatis defined. It makes the behavior explicit and allows similar problems to be addressed in the future. But, like method 2 it allows adding delimeters in an unsafe way for these values.x-vrc-no-encode: true) as part of theSchema Objectto conditionally skip encoding.Same as method 4, but a vendor extension avoids conflating the data format with the encoding. This is better as the data format and encoding are not directly related.
allowReservedfor apathparameter.Same as method 5. This aligns with the direction of OpenAPI 3.2, but it is invalid in OpenAPI 3.0/3.1 and would intentionally violate the current specification.
This PR adopts option 3. It makes the smallest possible change by preserving literal parentheses during URL encoding while continuing to percent-encode all other reserved characters. The SDK could also fork the byte_serialize function, but that'd require embedding unsafe Rust in the SDK.
I tested this patch on 1.20.7 as I'm having the following issue on main: