karatelabs/karate · error · OAuth2Exception
Missing 'client_id' in OAuth config
Error message
Missing 'client_id' in OAuth config
What it means
buildAuthorizationUrl() requires 'client_id' in the OAuth config to identify the application to the provider's authorize endpoint. When the key is missing, an OAuth2Exception is thrown right after the authorizationUrl check, with this exact message.
Solutions
- Add 'client_id' to the config map with the value from your provider app registration
- Verify the key is exactly 'client_id' (snake_case)
- Load and inspect the resolved config before starting the flow
Example fix
// before
config.put("clientId", "abc");
// after
config.put("client_id", "abc"); Defensive patterns
Strategy: validation
Validate before calling
Object clientId = config.get("client_id");
if (clientId == null || clientId.toString().isBlank()) {
throw new IllegalArgumentException("config.client_id is required");
} Type guard
static String requireConfigKey(Map<String, Object> config, String key) {
Object v = config.get(key);
if (!(v instanceof String s) || s.isBlank()) {
throw new IllegalArgumentException("Missing '" + key + "' in OAuth config");
}
return s;
} Try / catch
try {
String url = handler.authUrl(pkce, redirectUri);
} catch (OAuth2Exception e) {
if (e.getMessage().contains("client_id")) {
throw new ConfigurationException("Add client_id to OAuth config", e);
}
throw e;
} Prevention
- Use snake_case keys exactly as the handler expects (client_id, not clientId)
- Validate all required keys together before starting the flow
- Centralize config loading so required-field checks happen once
- Store credentials via env/secret manager and inject at load time with presence checks
When it happens
Trigger: authUrl() invoked with a config map lacking 'client_id' — e.g. the secret was set but the ID was forgotten, the key was named 'clientId' instead of 'client_id', or the config loader skipped the field.
Common situations: Naming-convention mismatches (camelCase vs snake_case) after migrating config formats, incomplete app registration, or constructing config maps by hand.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Missing 'authorizationUrl' in OAuth config
- Missing 'url' (token endpoint) in OAuth config
- Authorization flow failed: " + e.getMessage()
- Token request failed: " + error + (desc != null ? " - " +…
- Invalid callbackPort: " + portValue
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/6ad7b31dbc90fa09.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java:139
} finally {
if (callbackServer != null) {
callbackServer.stop();
}
}
}
/**
* Build authorization URL with all required parameters
*/
private String buildAuthorizationUrl(PkceGenerator pkce, String redirectUri) {
String authzEndpoint = (String) config.get("authorizationUrl");
if (authzEndpoint == null) {
throw new OAuth2Exception("Missing 'authorizationUrl' in OAuth config");
}
String clientId = (String) config.get("client_id");
if (clientId == null) {
throw new OAuth2Exception("Missing 'client_id' in OAuth config");
}
String scope = (String) config.getOrDefault("scope", "");
StringBuilder url = new StringBuilder(authzEndpoint);
url.append(authzEndpoint.contains("?") ? "&" : "?");
url.append("response_type=code");
url.append("&client_id=").append(urlEncode(clientId));
url.append("&redirect_uri=").append(urlEncode(redirectUri));
url.append("&code_challenge=").append(urlEncode(pkce.getChallenge()));
url.append("&code_challenge_method=").append(pkce.getMethod());
if (!scope.isEmpty()) {
url.append("&scope=").append(urlEncode(scope));
}
// Add state for CSRF protection
String state = generateState();View on GitHub (pinned to a22eb90246)