karatelabs/karate · error · OAuth2Exception

Invalid callbackPorts type: " + portsValue.getClass()

Error message

Invalid callbackPorts type: " + portsValue.getClass()

What it means

Type guard in parsePortList: callbackPorts in the OAuth2 authorization-code config must be a string or list of ports, but a value of an unexpected type (portsValue.getClass() is interpolated into the message) was supplied. Fix the config so callbackPorts is a comma-separated string or a compatible list.

Solutions

  1. Provide callbackPorts as a comma-separated String ("9090,9091") or an int[] (new int[]{9090, 9091}).
  2. If you have a List<Long>/JS array, convert it: convert each element to int and build an int[].
  3. Check the docs/config schema for the accepted callbackPorts types and fix the assignment.

Example fix

// before
config.callbackPorts = [9090, 9091]; // JS/JSON list
// after
config.callbackPorts = "9090,9091"; // or new int[]{9090, 9091}
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = config.get("callbackPorts");
if (!(v instanceof String) && !(v instanceof int[])) {
    throw new IllegalArgumentException("callbackPorts must be a String or int[], got: " + v.getClass());
}

Type guard

boolean isAcceptedCallbackPortsType(Object v) {
    return v instanceof String || v instanceof int[];
}
// convert a JS/JSON numeric array:
String portsToString(java.util.List<Number> list) {
    StringBuilder sb = new StringBuilder();
    for (Number n : list) { if (sb.length() > 0) sb.append(','); sb.append(n.intValue()); }
    return sb.toString();
}

Try / catch

try {
    handler.token();
} catch (OAuth2Exception e) {
    if (e.getMessage().startsWith("Invalid callbackPorts type:")) {
        logger.error("Use a comma-separated String or int[] for callbackPorts: {}", e.getMessage());
    }
}

Prevention

When it happens

Trigger: callbackPorts configured as a List, Map, Long array, or other object instead of a comma-separated String or int[].

Common situations: Passing a JS array or JSON array directly where the handler expects the documented string form (or int[]); a YAML list binding to java.util.List; programmatic config with the wrong collection type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/81e442d9112a829f. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java:304

    }

    /**
     * Parse comma-separated port list
     */
    private int[] parsePortList(Object portsValue) {
        if (portsValue instanceof String) {
            String[] parts = ((String) portsValue).split(",");
            int[] ports = new int[parts.length];
            for (int i = 0; i < parts.length; i++) {
                try {
                    ports[i] = Integer.parseInt(parts[i].trim());
                } catch (NumberFormatException e) {
                    throw new OAuth2Exception("Invalid port in callbackPorts: " + parts[i]);
                }
            }
            return ports;
        }
        throw new OAuth2Exception("Invalid callbackPorts type: " + portsValue.getClass());
    }

    private String generateState() {
        // Simple state generation - could be more sophisticated
        return java.util.UUID.randomUUID().toString();
    }

    private String urlEncode(String value) {
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
        } catch (UnsupportedEncodingException e) {
            throw new OAuth2Exception("URL encoding failed", e);
        }
    }

    private String truncate(String value) {
        if (value == null) {
            return "(empty)";

View on GitHub (pinned to a22eb90246)