{"record":{"id":"94894393a0ddc9ec","repo":"code4craft/webmagic","slug":"only-one-of-extractby-comboextract-extractbyurl","errorCode":null,"errorMessage":"Only one of 'ExtractBy ComboExtract ExtractByUrl' can be added to a field!","messagePattern":"Only one of 'ExtractBy ComboExtract ExtractByUrl' can be added to a field!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"webmagic-extension/src/main/java/us/codecraft/webmagic/model/PageModelExtractor.java","lineNumber":72,"sourceCode":"\n    private Logger logger = LoggerFactory.getLogger(getClass());\n\n    public static PageModelExtractor create(Class clazz) {\n        PageModelExtractor pageModelExtractor = new PageModelExtractor();\n        pageModelExtractor.init(clazz);\n        return pageModelExtractor;\n    }\n\n    private void init(Class clazz) {\n        this.clazz = clazz;\n        initClassExtractors();\n        fieldExtractors = new ArrayList<FieldExtractor>();\n        for (Field field : ClassUtils.getFieldsIncludeSuperClass(clazz)) {\n            field.setAccessible(true);\n            FieldExtractor fieldExtractor = getAnnotationExtractBy(clazz, field);\n            FieldExtractor fieldExtractorTmp = getAnnotationExtractCombo(clazz, field);\n            if (fieldExtractor != null && fieldExtractorTmp != null) {\n                throw new IllegalStateException(\"Only one of 'ExtractBy ComboExtract ExtractByUrl' can be added to a field!\");\n            } else if (fieldExtractor == null && fieldExtractorTmp != null) {\n                fieldExtractor = fieldExtractorTmp;\n            }\n            fieldExtractorTmp = getAnnotationExtractByUrl(clazz, field);\n            if (fieldExtractor != null && fieldExtractorTmp != null) {\n                throw new IllegalStateException(\"Only one of 'ExtractBy ComboExtract ExtractByUrl' can be added to a field!\");\n            } else if (fieldExtractor == null && fieldExtractorTmp != null) {\n                fieldExtractor = fieldExtractorTmp;\n            }\n            if (fieldExtractor != null) {\n                fieldExtractor.setObjectFormatter(new ObjectFormatterBuilder().setField(field).build());\n                fieldExtractors.add(fieldExtractor);\n            }\n        }\n    }\n\n    private FieldExtractor getAnnotationExtractByUrl(Class clazz, Field field) {\n        FieldExtractor fieldExtractor = null;","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/code4craft/webmagic/blob/67816a19d68a4fec4657bf1336227e046e251df2/webmagic-extension/src/main/java/us/codecraft/webmagic/model/PageModelExtractor.java#L54-L90","documentation":"PageModelExtractor.init validates annotated model fields: a field may carry at most one of @ExtractBy, @ComboExtract, or @ExtractByUrl. When getAnnotationExtractBy and getAnnotationExtractCombo both return extractors for the same field, IllegalStateException is thrown at model setup time.","triggerScenarios":"Declaring a model field annotated with both @ExtractBy and @ComboExtract, then calling OOSpider.create(...) or PageModelExtractor.create(clazz).","commonSituations":"Copy-pasting annotations between fields and leaving two behind; merging extractor classes where one field gained @ComboExtract without removing @ExtractBy.","solutions":["Remove one of the conflicting annotations from the field","Move one extraction to a separate field if both values are needed","Use @ComboExtract alone to combine multiple sub-extractors instead of stacking @ExtractBy"],"exampleFix":"// before\n@ExtractBy(\"//title/text()\")\n@ComboExtract(@ExtractBy(value = \"//h1/text()\"))\nprivate String title;\n// after\n@ExtractBy(\"//title/text()\")\nprivate String title;","handlingStrategy":"validation","validationCode":"for (Field f : modelClass.getDeclaredFields()) { int n = countAnnotations(f, ExtractBy.class, ComboExtract.class, ExtractByUrl.class); if (n > 1) throw new IllegalStateException(f + \" has multiple extract annotations\"); }","typeGuard":null,"tryCatchPattern":"try { spider = OOSpider.create(Model.class, pipeline, urls); } catch (IllegalStateException e) { log.error(\"model annotation conflict: \" + e.getMessage(), e); }","preventionTips":["One extraction annotation per model field","Review fields after copy-paste or refactors","Run PageModelExtractor.create() in a startup smoke test"],"tags":["webmagic","model-annotation","illegal-state","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"67816a19d68a4fec4657bf1336227e046e251df2","analyzedAt":"2026-09-08T11:15:28.425Z","contentChangedAt":"2026-09-08T11:15:28.425Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}