{"record":{"id":"18193aec0c54a6b6","repo":"apache/seatunnel","slug":"cannot-reliably-determine-vertex-assignment-for-ta","errorCode":null,"errorMessage":"Cannot reliably determine vertex assignment for table '{}' metric '{}' (isArray=false) with {} configured vertices, using table name only to avoid incorrect attribution","messagePattern":"Cannot reliably determine vertex assignment for table '(.+?)' metric '(.+?)' \\(isArray=false\\) with (.+?) configured vertices, using table name only to avoid incorrect attribution","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java","lineNumber":827,"sourceCode":"            return;\n        }\n\n        List<String> vertexIdentifiers =\n                tableToVertexIdentifiersMap == null\n                        ? null\n                        : tableToVertexIdentifiersMap.get(tableName);\n\n        if (vertexIdentifiers == null || vertexIdentifiers.isEmpty()) {\n            putMetricToMap(metricName, tableName, metricNode, tableMetricsMaps);\n            return;\n        }\n\n        if (!metricNode.isArray()) {\n            String metricKey = tableName;\n            if (vertexIdentifiers.size() == 1) {\n                metricKey = vertexIdentifiers.get(0) + \".\" + tableName;\n            } else {\n                log.warn(\n                        \"Cannot reliably determine vertex assignment for table '{}' metric '{}' (isArray=false) with {} configured vertices, using table name only to avoid incorrect attribution\",\n                        tableName,\n                        metricName,\n                        vertexIdentifiers.size());\n            }\n            putMetricToMap(metricName, metricKey, metricNode, tableMetricsMaps);\n            return;\n        }\n\n        // Prefer tag-based attribution to handle partial/mismatched arrays reliably.\n        ObjectMapper mapper = new ObjectMapper();\n        Map<String, ArrayNode> metricsByIdentifier = new HashMap<>();\n        ArrayNode unassignedMetrics = null;\n        for (JsonNode node : metricNode) {\n            String identifier = extractVertexIdentifierFromMetricNode(node);\n            if (StringUtils.isNotBlank(identifier) && vertexIdentifiers.contains(identifier)) {\n                metricsByIdentifier\n                        .computeIfAbsent(identifier, k -> mapper.createArrayNode())","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java#L809-L845","documentation":"When aggregating per-table job metrics for the REST API, BaseService.processMetric() expects metric values to be attributable to specific pipeline vertices (identified per table). If the metric JSON node is not an array and the number of configured vertex identifiers for the table is not exactly 1, the service cannot safely attribute the value to a vertex, so it logs this warning and falls back to using just the table name as the metric key.","triggerScenarios":"A table's metric response for a given metric name is a single (non-array) JSON node while the table is configured with 0 or >1 vertex identifiers — e.g. multi-vertex tables receiving aggregated single-value metrics.","commonSituations":"Source/sink with multiple parallelism reported a merged metric value; metrics format produced by an older/newer engine version differs from what the REST aggregator expects; table used in multiple vertices of the DAG.","solutions":["Inspect the raw job metrics for the table to see why a scalar value is returned for a multi-vertex metric.","Check engine version consistency — metric serialization format must match the REST service expectations.","Accept the fallback if table-level attribution is sufficient; the warning explicitly says data is still reported under the table name.","If the table should have exactly one vertex, verify the job DAG/table configuration."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure a single-vertex expectation matches the payload shape\nJsonNode metricNode = raw.get(metricName);\nif (!metricNode.isArray() && vertexIdentifiers.size() != 1) {\n    // expect table-name-level attribution only\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Poll metrics only after all vertices are initialized","Keep engine and REST service versions aligned","Verify table-to-vertex configuration in the job DAG","Treat scalar metrics on multi-vertex tables as table-level, not vertex-level"],"tags":["metrics","rest-api","attribution"],"backgroundTag":"unexpected-response-shape","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}