{"record":{"id":"c1bd77db625b246c","repo":"quarkusio/quarkus","slug":"claim-value-at-path-s-is-not-a-string","errorCode":null,"errorMessage":"Claim value at path '%s' is not a string","messagePattern":"Claim value at path '(.+?)' is not a string","errorType":"exception","errorClass":"io.quarkus.oidc.runtime.OIDCException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcUtils.java","lineNumber":337,"sourceCode":"            return Arrays.asList(claimValue.toString().split(sep));\n        } else {\n            return Collections.emptyList();\n        }\n    }\n\n    private static String[] splitClaimPath(String claimPath) {\n        return claimPath.indexOf('/') > 0 ? CLAIM_PATH_PATTERN.split(claimPath) : new String[] { claimPath };\n    }\n\n    static String findStringClaimValue(String claimPath, JsonObject json) {\n        Object value = findClaimValue(claimPath, json, splitClaimPath(claimPath), 0);\n        if (value == null) {\n            return null;\n        }\n        if (value instanceof String) {\n            return (String) value;\n        }\n        throw new OIDCException(\"Claim value at path '\" + claimPath + \"' is not a string\");\n    }\n\n    private static Object findClaimValue(String claimPath, JsonObject json, String[] pathArray, int step) {\n        Object claimValue = json.getValue(pathArray[step].replace(\"\\\"\", \"\"));\n        if (claimValue == null) {\n            LOG.debugf(\"No claim exists at the path '%s' at the path segment '%s'\", claimPath, pathArray[step]);\n        } else if (step + 1 < pathArray.length) {\n            if (claimValue instanceof JsonObject) {\n                int nextStep = step + 1;\n                return findClaimValue(claimPath, (JsonObject) claimValue, pathArray, nextStep);\n            } else {\n                LOG.debugf(\"Claim value at the path '%s' is not a json object\", claimPath);\n            }\n        }\n\n        return claimValue;\n    }\n","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcUtils.java#L319-L355","documentation":"Quarkus OIDC's OidcUtils.findStringClaimValue throws OIDCException when a token claim located at the given path exists but its value is not a JSON string. Code expecting a string claim (e.g. 'sub', 'preferred_username') receives a number, boolean, array, or object instead.","triggerScenarios":"Calling findStringClaimValue (or configured claim paths like name/subject claim paths) on a token where the claim at claimPath holds a non-string JSON value (e.g. an integer 'sub', a JSON object), so the instanceof String check fails and OIDCException is thrown.","commonSituations":"IdP-issued tokens with numeric 'sub' claims (some providers use integers); custom claim mappings pointing at nested objects or arrays; misconfigured quarkus.oidc token.claim-path settings pointing at the wrong claim.","solutions":["Fix the claim path configuration so it points to an actual string claim in the token","Transform the token at the identity provider so the claim is emitted as a string (e.g. 'sub' as string)","Use a claim-value accessor that handles non-string JSON types instead of findStringClaimValue"],"exampleFix":"// before: 'sub': 12345 (number) -> OIDCException\n// after: configure IdP or mapping so 'sub': \"12345\" (string)","handlingStrategy":"type-guard","validationCode":"Object claim = jwtJson.getJson(\"claimPath\");\nif (!(claim instanceof String)) throw new IllegalArgumentException(\"Claim must be a string: \" + claim);","typeGuard":"boolean isStringClaim(Object v) { return v instanceof String; }","tryCatchPattern":"try { value = findStringClaimValue(token, claimPath); } catch (OIDCException e) { log.warn(\"Claim {} not a string, falling back\", claimPath); value = String.valueOf(findClaimValue(...)); }","preventionTips":["Inspect decoded tokens (jwt.io) before wiring claim paths","Configure the IdP to emit string claims (e.g. string 'sub')","Write a startup test decoding a sample token and asserting claim types"],"tags":["oidc","token-claims","json"],"backgroundTag":"claim-type-mismatch","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}