Tencent/VasSonic · error · UnsupportedOperationException
This isn't a hierarchical URI.
Error message
This isn't a hierarchical URI.
What it means
getQueryParameterNames(Uri) mirrors android.net.Uri's behavior and only supports hierarchical (opaque=false) URIs. When the URI is opaque (e.g. mailto:foo@bar.com), it throws UnsupportedOperationException because opaque URIs have no query part to parse.
Solutions
- Check uri.isOpaque() before calling and return an empty set or skip parameter parsing for opaque URIs
- Normalize the URL to a hierarchical form (ensure scheme://host) before passing it to Sonic
- Only invoke Sonic session flows with http/https URLs, which are always hierarchical
- Add an isHierarchical guard in the wrapper that extracts query parameters
Example fix
// before
Set<String> names = runtime.getQueryParameterNames(uri); // throws for opaque URIs
// after
Set<String> names = (uri != null && uri.isHierarchical())
? runtime.getQueryParameterNames(uri)
: Collections.emptySet(); Defensive patterns
Strategy: validation
Validate before calling
if (uri == null || uri.isOpaque()) {
return Collections.emptySet(); // skip param extraction
} Type guard
// Java
static boolean isParseableUri(Uri uri) {
return uri != null && uri.isHierarchical();
} Try / catch
try {
names = runtime.getQueryParameterNames(uri);
} catch (UnsupportedOperationException e) {
names = Collections.emptySet(); // opaque URI: no query params
} Prevention
- Only feed http/https URLs into Sonic session flows
- Check isOpaque()/isHierarchical() before URI parsing
- Ensure custom deep-link schemes include the '//' authority part
When it happens
Trigger: Calling SonicRuntime.getQueryParameterNames() with a Uri for which uri.isOpaque() returns true — non-hierarchical schemes like mailto:, tel:, or custom schemes without '//'.
Common situations: Passing a session URL that is actually an intent/deep-link opaque URI into Sonic's parameter extraction; mishandled scheme strings like 'sonic:foo' instead of 'sonic://host/path'; extracting params from URIs built via Uri.parse on non-hierarchical strings.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- SonicDBHelper::createInstance() needs to be called before…
- SonicEngine::createInstance() needs to be called before…
- SonicRuntime context con not be null!
- Attempt to verify non-SSL socket
- Cannot verify SSL socket without session
AI-assisted analysis of Tencent/VasSonic@59936beff6 (2026-09-08).
Data as JSON: /api/errors/50ea0f282acb77ab.
Report an issue: GitHub.
Appendix: source
Thrown at sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicRuntime.java:130
return null;
}
/**
* Returns a set of the unique names of all query parameters. Iterating
* over the set will return the names in order of their first occurrence.
*
* @throws UnsupportedOperationException if this isn't a hierarchical URI
*
* @param uri The uri
* @return A set of decoded names
*/
public Set<String> getQueryParameterNames(Uri uri) {
if (uri == null) {
return Collections.emptySet();
}
if (uri.isOpaque()) {
throw new UnsupportedOperationException("This isn't a hierarchical URI.");
}
String query = uri.getEncodedQuery();
if (query == null) {
return Collections.emptySet();
}
Set<String> names = new LinkedHashSet<String>();
int start = 0;
do {
int next = query.indexOf('&', start);
int end = (next == -1) ? query.length() : next;
int separator = query.indexOf('=', start);
if (separator > end || separator == -1) {
separator = end;
}
View on GitHub (pinned to 59936beff6)