{"record":{"id":"05d51cd37c4e20d4","repo":"pinpoint-apm/pinpoint","slug":"unknown-primaryforfieldandtagrelation","errorCode":null,"errorMessage":"Unknown primaryForFieldAndTagRelation: ","messagePattern":"Unknown primaryForFieldAndTagRelation: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"otlpmetric/otlpmetric-web/src/main/java/com/navercorp/pinpoint/otlp/web/service/OtlpMetricWebServiceImpl.java","lineNumber":198,"sourceCode":"                }\n            }\n\n        return metricData;\n    }\n\n    private MetricData createEmptyMetricData(TimeWindow timeWindow, ChartType chartType) {\n        List<Long> windows = timeWindow.getTimeseriesWindows();\n        return new MetricData(windows, chartType, EMPTY_STRING, \"There is no metadata for the metric query.\");\n    }\n\n    private String getLegendName(OtlpMetricDataQueryParameter chartQueryParameter, PrimaryForFieldAndTagRelation primaryForFieldAndTagRelation) {\n        switch (primaryForFieldAndTagRelation) {\n            case FIELD:\n                return chartQueryParameter.getRawTags();\n            case TAG:\n                return chartQueryParameter.getFieldName();\n            default:\n                throw new IllegalArgumentException(\"Unknown primaryForFieldAndTagRelation: \" + primaryForFieldAndTagRelation);\n        }\n    }\n\n\n    private void addMetricValue(TimeWindow timeWindow,\n                                List<DataPoint> meticDataList, MetricData metricData, String legendName, String version){\n        TimeSeriesBuilder timeSeriesBuilder = new TimeSeriesBuilder(timeWindow);\n        List<DataPoint> metricPointList = timeSeriesBuilder.build(MetricPoints::createUnCollectedPoint, meticDataList);\n        List<Number> valueList = metricPointList.stream().map(DataPoint::getValue).collect(Collectors.toList());\n\n        metricData.addMetricValue(new MetricValue(legendName, valueList, version));\n\n//                if (otlpMetricChartResults != null) {\n        // TODO : (minwoo) Get summary data\n        //                    if ((metricData.hasSummaryField()) && (chartFieldView != null)) {\n\n\n//                        OtlpMetricDataQueryParameter chartQueryParameter = setupQueryParameter(builder, key);","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/otlpmetric/otlpmetric-web/src/main/java/com/navercorp/pinpoint/otlp/web/service/OtlpMetricWebServiceImpl.java#L180-L216","documentation":"getLegendName derives chart legend labels from the metric definition's primaryForFieldAndTagRelation enum, which must be FIELD or TAG (the two valid cardinality anchors). When the stored/serialized value is anything else — including null from an unset or legacy record — the default branch throws IllegalArgumentException with the offending value appended. (The trailing colon with nothing after it in some logs indicates the value's toString() was null or empty.)","triggerScenarios":"Querying metric data (getMetricData → getLegendName) for a metric definition whose primaryForFieldAndTagRelation field is null or an unrecognized value — e.g. data written by an older Pinpoint version before the enum existed, or a manually edited DB row / API payload with a typo like \"Field\" (wrong case) or \"fieldAndTag\".","commonSituations":"1) Legacy rows in the OTLP metric-definition storage predating the FIELD/TAG enum. 2) REST clients sending lowercase/mis-spelled relation values. 3) Deserialization frameworks mapping unknown strings to null. 4) Bug where the definition was saved without computing the primary relation (validateCountOfTagAndField enforces 1:N or N:1, but the primary flag may not have been set).","solutions":["Fix the stored definition so primaryForFieldAndTagRelation is FIELD or TAG (re-save via the web UI or update the DB row).","Normalize enum parsing upstream: reject definitions whose relation is not FIELD/TAG at save time (validate() should set/guard it).","If data comes from an old version, run a migration/backfill setting the field for all definitions.","For a tolerant read path, fall back to a default legend instead of throwing (see exampleFix)."],"exampleFix":"// before\ndefault:\n    throw new IllegalArgumentException(\"Unknown primaryForFieldAndTagRelation: \" + primaryForFieldAndTagRelation);\n// after\ndefault:\n    if (primaryForFieldAndTagRelation == null) {\n        return chartQueryParameter.getRawTags(); // legacy fallback\n    }\n    throw new IllegalArgumentException(\"Unknown primaryForFieldAndTagRelation: \" + primaryForFieldAndTagRelation);","handlingStrategy":"try-catch","validationCode":"function validateRelation(def) {\n  if (def.primaryForFieldAndTagRelation !== 'FIELD' && def.primaryForFieldAndTagRelation !== 'TAG') {\n    throw new Error(\"primaryForFieldAndTagRelation must be FIELD or TAG, got: \" + def.primaryForFieldAndTagRelation);\n  }\n}","typeGuard":"boolean isValidRelation(AppMetricDefinition definition) {\n    return definition.getPrimaryForFieldAndTagRelation() == FieldAndTagRelation.FIELD\n        || definition.getPrimaryForFieldAndTagRelation() == FieldAndTagRelation.TAG;\n}","tryCatchPattern":"try {\n    String legend = getLegendName(primaryForFieldAndTagRelation, chartQueryParameter);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Falling back to default legend; definition relation invalid: {}\", e.getMessage());\n    legend = chartQueryParameter.getFieldName();\n}","preventionTips":["Enforce FIELD/TAG validity at definition save time, not only at query time.","Backfill or migrate rows created before the enum was introduced.","Use exact enum constants in API clients; beware case-sensitive string serialization.","Log the full definition id when this throws so bad rows can be located quickly."],"tags":["java","enum","pinpoint","invalid-state","legend"],"backgroundTag":"invalid-enum-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}