{"record":{"id":"357c927fe652000d","repo":"pinpoint-apm/pinpoint","slug":"timewindow-is-required","errorCode":null,"errorMessage":"TimeWindow is required.","messagePattern":"TimeWindow is required\\.","errorType":"validation","errorClass":"InvalidParameterException","httpStatus":null,"severity":"error","filePath":"otlpmetric/otlpmetric-web/src/main/java/com/navercorp/pinpoint/otlp/web/vo/OtlpMetricChartQueryParameter.java","lineNumber":127,"sourceCode":"\n        public Builder setLimit(int limit) {\n            this.limit = Ints.constrainToRange(limit, 50, 200);\n            return self();\n        }\n\n        public Builder setTimeWindow(TimeWindow timeWindow) {\n            this.timeWindow = timeWindow;\n            this.range = timeWindow.getWindowRange();\n            this.timeSize = timeWindow.getWindowSlotSize();\n            this.timePrecision = TimePrecision.newTimePrecision(TimeUnit.MILLISECONDS, timeWindow.getWindowSlotSize());\n            this.limit = timeWindow.getWindowRangeCount();\n            return self();\n        }\n\n        @Override\n        public OtlpMetricChartQueryParameter build() {\n            if (timeWindow == null) {\n                throw new InvalidParameterException(\"TimeWindow is required.\");\n            }\n\n            return new OtlpMetricChartQueryParameter(this);\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"OtlpMetricChartQueryParameter{\" +\n                \"serviceName='\" + serviceName + '\\'' +\n                \", applicationName='\" + applicationName + '\\'' +\n                \", agentId='\" + agentId + '\\'' +\n                \", metricGroupName='\" + metricGroupName + '\\'' +\n                \", metricName='\" + metricName + '\\'' +\n                \", fieldName='\" + fieldName + '\\'' +\n                \", tags=\" + tags +\n                \", version='\" + version + '\\'' +\n                \", aggregationFunction=\" + aggregationFunction +","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/otlpmetric/otlpmetric-web/src/main/java/com/navercorp/pinpoint/otlp/web/vo/OtlpMetricChartQueryParameter.java#L109-L145","documentation":"OtlpMetricChartQueryParameter uses a builder pattern, and build() enforces that a TimeWindow was set before constructing the immutable query parameter object. If timeWindow is null, an InvalidParameterException is thrown. The TimeWindow (range/r interval) is required for chart queries so the service can compute aggregation buckets.","triggerScenarios":"Calling OtlpMetricChartQueryParameter.ChartQueryBuilder.build() without having called timeWindow(...) on the builder first.","commonSituations":"New code paths constructing chart query parameters forget the timeWindow step; refactors that changed the builder chain; unit tests exercising build() with partial parameters; conditional logic that skips setting timeWindow when a request lacks a time range.","solutions":["Always call .timeWindow(new TimeWindow(from, to, interval)) on the builder before build().","Derive the TimeWindow from the incoming request's from/to parameters and validate them at the controller layer.","Add a unit test that exercises the full builder chain so a missing mandatory field fails in CI instead of at runtime."],"exampleFix":"// before\nOtlpMetricChartQueryParameter param = OtlpMetricChartQueryParameter.newChartQueryBuilder()\n        .setApplicationName(appName)\n        .build();\n// after\nOtlpMetricChartQueryParameter param = OtlpMetricChartQueryParameter.newChartQueryBuilder()\n        .setApplicationName(appName)\n        .setTimeWindow(new TimeWindow(from, to, interval))\n        .build();","handlingStrategy":"validation","validationCode":"if (timeWindow == null) {\n    throw new IllegalArgumentException(\"request must include from/to/interval to build a TimeWindow\");\n}","typeGuard":"boolean isChartParameterComplete(OtlpMetricChartQueryParameter.ChartQueryBuilder b) {\n    return b.getTimeWindow() != null; // check before build()\n}","tryCatchPattern":"try {\n    OtlpMetricChartQueryParameter p = builder.build();\n} catch (InvalidParameterException e) {\n    return ResponseEntity.badRequest().body(\"time range (from/to/interval) is required\");\n}","preventionTips":["Set timeWindow immediately after creating the builder, before other optional fields","Validate request time-range parameters at the controller layer","Add builder tests covering the full mandatory chain"],"tags":["java","builder","validation","otlp-metrics"],"backgroundTag":"missing-required-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}