{"record":{"id":"dc155cff51838ebb","repo":"apache/seatunnel","slug":"pulsarconnectorerrorcode-deserialization-schema-no","errorCode":"PulsarConnectorErrorCode.DESERIALIZATION_SCHEMA_NOT_FOUND","errorMessage":"No consumer metadata found for table '%s'. Default table path: '%s'. Available tables: [%s]. This is likely a bug in the multi-table routing logic.","messagePattern":"No consumer metadata found for table '(.+?)'\\. Default table path: '(.+?)'\\. Available tables: \\[(.+?)\\]\\. This is likely a bug in the multi-table routing logic\\.","errorType":"error_code","errorClass":"PulsarConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-pulsar/src/main/java/org/apache/seatunnel/connectors/seatunnel/pulsar/source/reader/PulsarSourceReader.java","lineNumber":325,"sourceCode":"    private TablePath resolveTablePath(PulsarPartitionSplit split) {\n        return split.getTablePath() != null ? split.getTablePath() : defaultTablePath;\n    }\n\n    private PulsarConsumerMetadata resolveConsumerMetadata(TablePath tablePath) {\n        PulsarConsumerMetadata metadata =\n                tablePath == null ? null : consumerMetadataMap.get(tablePath);\n        if (metadata == null && defaultTablePath != null) {\n            metadata = consumerMetadataMap.get(defaultTablePath);\n        }\n        if (metadata == null) {\n            String tablePathStr = tablePath != null ? tablePath.toString() : \"null\";\n            String defaultTablePathStr =\n                    defaultTablePath != null ? defaultTablePath.toString() : \"null\";\n            String availableTables =\n                    consumerMetadataMap.keySet().stream()\n                            .map(TablePath::toString)\n                            .collect(Collectors.joining(\", \"));\n            throw new PulsarConnectorException(\n                    PulsarConnectorErrorCode.DESERIALIZATION_SCHEMA_NOT_FOUND,\n                    String.format(\n                            \"No consumer metadata found for table '%s'. \"\n                                    + \"Default table path: '%s'. \"\n                                    + \"Available tables: [%s]. \"\n                                    + \"This is likely a bug in the multi-table routing logic.\",\n                            tablePathStr, defaultTablePathStr, availableTables));\n        }\n        return metadata;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private DeserializationSchema<T> resolveDeserializationSchema(TablePath tablePath) {\n        return (DeserializationSchema<T>)\n                resolveConsumerMetadata(tablePath).getDeserializationSchema();\n    }\n\n    private Collector<T> resolveCollector(","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-pulsar/src/main/java/org/apache/seatunnel/connectors/seatunnel/pulsar/source/reader/PulsarSourceReader.java#L307-L343","documentation":"Thrown by PulsarSourceReader.resolveConsumerMetadata when a record's table path has no entry in consumerMetadataMap. The reader keeps deserialization schema/consumer metadata per table for multi-table Pulsar sources; a record arriving for an unknown table indicates routing metadata was never registered, which the code flags as a bug in the multi-table routing logic.","triggerScenarios":"Reading a record whose topic maps to a TablePath not present in consumerMetadataMap — e.g. metadata() or resolveDeserializationSchema() called with a TablePath that no SourceReader/SplitEnumerator registered, or a split whose topics were not covered during metadata initialization.","commonSituations":"Multi-table (topic-pattern or table-routing) Pulsar source where the enumerator discovered a new topic after metadata was built; dynamic topic addition without a checkpoint/restart; mis-mapped topic-to-TablePath conversion producing a TablePath that differs in case/format from the registered one.","solutions":["Verify the split/topic enumeration registers consumer metadata for every topic the reader can receive (check the split enumerator's routing logic).","Compare the reported table path and the 'Available tables' list to spot case or format mismatches (e.g. database.table differences).","Restart the job so the enumerator re-discovers topics and rebuilds the metadata map.","If a genuinely new topic appeared at runtime, ensure the connector supports dynamic discovery or restrict the topic pattern to pre-registered tables.","If all metadata looks correct, file a bug with the full message including default table path and available tables — the code itself marks this an internal invariant violation."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before processing, confirm every topic of every split is registered\nsplits.forEach(s -> {\n    TablePath tp = toTablePath(s.getPartition());\n    if (!registeredMetadata.containsKey(tp)) {\n        throw new IllegalStateException(\"Unregistered table in split: \" + tp);\n    }\n});","typeGuard":null,"tryCatchPattern":"try { schema = resolveDeserializationSchema(tablePath); } catch (PulsarConnectorException e) { LOG.error(\"Routing bug: table {} not in metadata {}\", tablePath, e.getMessage()); throw e; }","preventionTips":["Keep topic-pattern discovery and metadata registration in lockstep","Normalize TablePath casing/format before lookup","Restrict topic patterns to pre-registered tables in multi-table jobs"],"tags":["pulsar","multi-table","routing","connector-bug"],"backgroundTag":"internal-invariant-violation","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"}