{"record":{"id":"a06b560dda82df91","repo":"alibaba/canal","slug":"hbasemapping-mode","errorCode":null,"errorMessage":"hbaseMapping.mode","messagePattern":"hbaseMapping\\.mode","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/config/MappingConfig.java","lineNumber":80,"sourceCode":"        this.hbaseMapping = hbaseMapping;\n    }\n\n    public AdapterMapping getMapping() {\n        return hbaseMapping;\n    }\n\n    public void validate() {\n        if (hbaseMapping.database == null || hbaseMapping.database.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.database\");\n        }\n        if (hbaseMapping.table == null || hbaseMapping.table.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.table\");\n        }\n        if (hbaseMapping.hbaseTable == null || hbaseMapping.hbaseTable.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.hbaseTable\");\n        }\n        if (hbaseMapping.mode == null) {\n            throw new NullPointerException(\"hbaseMapping.mode\");\n        }\n        if (hbaseMapping.rowKey != null && hbaseMapping.rowKeyColumn != null) {\n            throw new RuntimeException(\"已配置了复合主键作为RowKey，无需再指定RowKey列\");\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        MappingConfig config = (MappingConfig) o;\n\n        return hbaseMapping != null ? hbaseMapping.equals(config.hbaseMapping) : config.hbaseMapping == null;\n    }\n\n    @Override\n    public int hashCode() {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/config/MappingConfig.java#L62-L98","documentation":"MappingConfig.validate() requires HbaseMapping.mode (one of STRING/NATIVE/PHOENIX) to be non-null. Note HbaseMapping defaults mode to STRING, so hitting this means the YAML explicitly set mode to null or the value failed to deserialize into the Mode enum.","triggerScenarios":"HBase mapping YAML setting 'mode:' to null or to a value that is not STRING/NATIVE/PHOENIX (which would actually throw on enum binding); validate() during load.","commonSituations":"Setting an invalid mode string in the YAML; removing the default via explicit null; older canal version whose enum lacks PHOENIX.","solutions":["Set 'mode: STRING' (or NATIVE/PHOENIX) explicitly, or omit 'mode' to use the STRING default.","Confirm the mode value matches the enum constant exactly (case-sensitive).","Verify the canal version supports the chosen mode enum value.","Lint the YAML."],"exampleFix":"# before (invalid mode)\nhbaseMapping:\n  mode: STRING_TYPE\n\n# after\nhbaseMapping:\n  mode: STRING","handlingStrategy":"validation","validationCode":"MappingConfig cfg = ...;\nif (cfg.getHbaseMapping() == null || cfg.getHbaseMapping().getMode() == null) {\n    throw new IllegalArgumentException(\"hbaseMapping.mode must be STRING, NATIVE, or PHOENIX\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    config.validate();\n} catch (NullPointerException e) {\n    if (\"hbaseMapping.mode\".equals(e.getMessage())) {\n        logger.error(\"Set mode: STRING|NATIVE|PHOENIX or omit to default to STRING\");\n    }\n    throw e;\n}","preventionTips":["Omit mode to use the STRING default, or set it to a valid enum constant.","Confirm the canal build supports the chosen mode (e.g. PHOENIX).","Lint YAML enum values."],"tags":["hbase-adapter","config","validation","yaml","mode"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}