{"record":{"id":"30a5c23696afe084","repo":"quarkusio/quarkus","slug":"should-not-be-called-the-json-codec-is-the-fallba","errorCode":null,"errorMessage":"Should not be called, the JSON codec is the fallback","messagePattern":"Should not be called, the JSON codec is the fallback","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/codecs/Codecs.java","lineNumber":67,"sourceCode":"        public JsonCodec(Type clazz) {\n            if (clazz instanceof Class) {\n                this.clazz = (Class<?>) clazz;\n                this.type = null;\n            } else {\n                this.type = new TypeReference<>() {\n                    @Override\n                    public Type getType() {\n                        return clazz;\n                    }\n                };\n                this.clazz = null;\n            }\n            this.mapper = QuarkusJacksonJsonCodec.mapper();\n        }\n\n        @Override\n        public boolean canHandle(Type clazz) {\n            throw new UnsupportedOperationException(\"Should not be called, the JSON codec is the fallback\");\n        }\n\n        @Override\n        public byte[] encode(Object item) {\n            return Json.encodeToBuffer(item).getBytes();\n        }\n\n        @Override\n        public Object decode(byte[] payload) {\n            try {\n                if (clazz != null) {\n                    return Json.decodeValue(Buffer.buffer(payload), clazz);\n                } else {\n                    return mapper.readValue(payload, type);\n                }\n            } catch (Exception e) {\n                throw new RuntimeException(e);\n            }","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/codecs/Codecs.java#L49-L85","documentation":"Codecs contains the codec chain used to map Java values to Redis arguments. The fallback DefaultJsonCodec (used when no typed codec matches) intentionally throws UnsupportedOperationException from canHandle(Type) with this message, because canHandle must never be consulted on the fallback codec — it is chosen only after every other codec declines. Hitting this exception indicates a codec-chain implementation bug, not a user error.","triggerScenarios":"Registering the JSON fallback codec explicitly in a codec list so canHandle is called on it, or custom codec-dispatch code that iterates all codecs (including the fallback) calling canHandle, rather than using the fallback only as a last resort.","commonSituations":"Custom serialization frameworks or wrapper libraries re-implementing codec dispatch and calling canHandle on every registered codec; version changes in quarkus-redis-client altering the codec contract; unit tests invoking canHandle directly.","solutions":["Do not include the default JSON codec in a canHandle-dispatch list; reserve it as the terminal fallback.","In dispatch loops, stop at the first codec whose canHandle returns true and use the JSON codec only when none match.","If you need type checks on the JSON codec, wrap it in your own codec whose canHandle inspects the Type."],"exampleFix":"// before\nfor (Codec c : allCodecsIncludingJsonFallback) { if (c.canHandle(type)) ... } // throws\n// after\nfor (Codec c : typedCodecs) { if (c.canHandle(type)) return c; }\nreturn jsonFallbackCodec; // never call canHandle on it","handlingStrategy":"fallback","validationCode":"if (codec instanceof DefaultJsonCodec) {\n    // never ask canHandle on the JSON fallback; use it only when nothing else matches\n    throw new IllegalStateException(\"JSON fallback codec must be terminal in the dispatch chain\");\n}","typeGuard":"boolean isJsonFallback(io.quarkus.redis.datasource.codecs.Codec c) { return c != null && c.getClass().getSimpleName().contains(\"DefaultJson\"); }","tryCatchPattern":"try { handled = candidate.canHandle(type); } catch (UnsupportedOperationException e) { // fallback codec reached in dispatch — treat as 'no match' and use it directly\n  return candidate; }","preventionTips":["Treat the JSON codec as terminal: dispatch through typed codecs first, fall back to JSON last.","Never register the default JSON codec alongside codecs iterated with canHandle.","Check the quarkus-redis-client version when upgrading — the codec contract may have changed."],"tags":["redis","codec","unsupported-operation","internal-api"],"backgroundTag":"unsupported-operation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}