{"record":{"id":"df338f8f7095fa5d","repo":"apache/seatunnel","slug":"operator-s-requires-an-expectvalue-but-expectval","errorCode":null,"errorMessage":"Operator %s requires an expectValue, but expectValue is null","messagePattern":"Operator (.+?) requires an expectValue, but expectValue is null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/configuration/util/Condition.java","lineNumber":69,"sourceCode":"            T expectValue,\n            Option<?> compareOption,\n            ConditionExtension<T> extension) {\n        if (option == null) {\n            throw new IllegalArgumentException(\"Condition option must not be null\");\n        }\n        if (operator == null) {\n            throw new IllegalArgumentException(\"Condition operator must not be null\");\n        }\n        if (operator.getSource() == ConditionOperator.Source.FIELD && compareOption == null) {\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"Operator %s requires a compareOption (cross-field comparison), but compareOption is null\",\n                            operator.name()));\n        }\n        if (operator.getArity() == ConditionOperator.Arity.BINARY\n                && operator.getSource() == ConditionOperator.Source.LITERAL\n                && expectValue == null) {\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"Operator %s requires an expectValue, but expectValue is null\",\n                            operator.name()));\n        }\n        if (operator == ConditionOperator.EXTENSION && extension == null) {\n            throw new IllegalArgumentException(\n                    \"Operator EXTENSION requires a non-null ConditionExtension\");\n        }\n        this.option = option;\n        this.operator = operator;\n        this.expectValue = expectValue;\n        this.compareOption = compareOption;\n        this.extension = extension;\n    }\n\n    public static <T> Condition<T> of(Option<T> option, T expectValue) {\n        return new Condition<>(option, expectValue);\n    }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/configuration/util/Condition.java#L51-L87","documentation":"ExcelReadStrategy.getSeaTunnelRowTypeInfo unconditionally throws FileConnectorException with UNSUPPORTED_OPERATION: the Excel reader never infers a schema from the file. (The message text mentions 'json file type' — a copy-over from another reader — but the semantics are that Excel sources require a user-defined schema.) Callers must supply the schema via the config/CatalogTable instead of asking the reader to discover it.","triggerScenarios":"Any call to getSeaTunnelRowTypeInfo(path) on the Excel read strategy — e.g. generic file-source code that tries to auto-derive a row type from the file path without a user-defined schema.","commonSituations":"Reusing a generic reader pipeline that calls schema inference for all formats; migrating a job from a format with schema inference (like CSV/JSON inference paths) to Excel; missing the schema block in the Excel source config.","solutions":["Define the schema explicitly in the Excel source configuration (schema with field names and types) so schema inference is never attempted.","Do not call getSeaTunnelRowTypeInfo for Excel sources; obtain the row type from the user-defined CatalogTable instead.","If you own the calling code, branch on the read strategy type and skip inference for Excel."],"exampleFix":"// before\nSeaTunnelRowType rowType = reader.getSeaTunnelRowTypeInfo(path); // always throws for Excel\n// after\n// declare schema in the source config and use the user-defined row type\nSeaTunnelRowType rowType = userDefinedRowTypeWithPartition;","handlingStrategy":"type-guard","validationCode":"java\n// Do not call schema inference for Excel sources; require user-defined schema first\nif (strategy instanceof ExcelReadStrategy && userDefinedRowType == null) {\n    throw new IllegalArgumentException(\"Excel source requires user-defined schema (config schema block)\");\n}","typeGuard":"java\nif (strategy instanceof ExcelReadStrategy) {\n    // never call getSeaTunnelRowTypeInfo; use the user-defined row type\n    SeaTunnelRowType rowType = userDefinedRowType;\n}","tryCatchPattern":"java\ntry {\n    rowType = strategy.getSeaTunnelRowTypeInfo(path);\n} catch (FileConnectorException e) {\n    rowType = userDefinedRowType; // Excel always requires user-defined schema\n}","preventionTips":["Define the schema explicitly in the Excel source configuration","Branch on reader/strategy type before attempting schema inference","Ignore the 'json file type' wording in the message — it applies to the Excel strategy"],"tags":["excel","schema","unsupported","connector-file"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}