{"record":{"id":"da5d4a409160e1c9","repo":"apache/flink","slug":"cannot-create-empty-classifier-chain","errorCode":null,"errorMessage":"Cannot create empty classifier chain.","messagePattern":"Cannot create empty classifier chain\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-connectors/flink-connector-base/src/main/java/org/apache/flink/connector/base/sink/throwable/FatalExceptionClassifier.java","lineNumber":67,"sourceCode":"\n        if (chainedClassifier != null) {\n            return chainedClassifier.isFatal(err, throwableConsumer);\n        } else {\n            return true;\n        }\n    }\n\n    public static FatalExceptionClassifier withRootCauseOfType(\n            Class<? extends Throwable> type, Function<Throwable, Exception> mapper) {\n        return new FatalExceptionClassifier(\n                err -> ExceptionUtils.findThrowable(err, type).isPresent(), mapper);\n    }\n\n    public static FatalExceptionClassifier createChain(FatalExceptionClassifier... classifiers) {\n        Set<FatalExceptionClassifier> importedClassifiers = new HashSet<>();\n\n        if (classifiers.length == 0) {\n            throw new IllegalArgumentException(\"Cannot create empty classifier chain.\");\n        }\n\n        FatalExceptionClassifier tailClassifier = classifiers[0];\n        importedClassifiers.add(tailClassifier);\n\n        for (int i = 1; i < classifiers.length; ++i) {\n            if (importedClassifiers.contains(classifiers[i])) {\n                throw new IllegalArgumentException(\n                        \"Wrong classifier chain; Circular chain of classifiers detected.\");\n            }\n\n            tailClassifier.chainedClassifier = classifiers[i];\n            tailClassifier = classifiers[i];\n            importedClassifiers.add(tailClassifier);\n        }\n\n        return classifiers[0];\n    }","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-connectors/flink-connector-base/src/main/java/org/apache/flink/connector/base/sink/throwable/FatalExceptionClassifier.java#L49-L85","documentation":"Thrown as an IllegalArgumentException by FatalExceptionClassifier.createChain when called with zero arguments. createChain links FatalExceptionClassifier instances into a chain for cascaded exception classification. An empty chain has no meaning and is rejected immediately as a programming error.","triggerScenarios":"Calling FatalExceptionClassifier.createChain() with no varargs arguments, or passing an empty array — e.g., createChain(new FatalExceptionClassifier[0]).","commonSituations":"A sink implementation builds its classifier chain dynamically from a list that happens to be empty; a configuration error causes all classifiers to be filtered out before createChain is called; defensive programming that constructs the chain from a collection without checking emptiness.","solutions":["Ensure at least one FatalExceptionClassifier is passed to createChain.","If the chain is built dynamically, guard with: if (classifiers.isEmpty()) { return empty/no-op classifier; } before calling createChain.","Review the caller to ensure the classifier list is always populated with at least one element."],"exampleFix":"// before — dynamic list might be empty\nFatalExceptionClassifier.createChain(classifiers.toArray(new FatalExceptionClassifier[0]));\n// after — guard against empty\nif (classifiers.isEmpty()) {\n    throw new IllegalStateException(\"At least one classifier required\");\n}\nFatalExceptionClassifier.createChain(classifiers.toArray(new FatalExceptionClassifier[0]));","handlingStrategy":"validation","validationCode":"// Validate before calling createChain\nif (classifiers == null || classifiers.length == 0) {\n    throw new IllegalArgumentException(\"At least one FatalExceptionClassifier is required\");\n}\nFatalExceptionClassifier.createChain(classifiers);","typeGuard":null,"tryCatchPattern":"try {\n    FatalExceptionClassifier.createChain(classifiers.toArray(new FatalExceptionClassifier[0]));\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"empty classifier chain\")) {\n        // provide a default classifier or skip chaining\n    }\n}","preventionTips":["Always pass at least one classifier to createChain.","Guard dynamic classifier lists with an emptiness check.","Use a default no-op classifier if the list is empty."],"tags":["async-sink","classifier","validation","programming-error"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}