{"record":{"id":"ece84891a330e168","repo":"alibaba/Sentinel","slug":"basedir-can-t-be-null","errorCode":null,"errorMessage":"baseDir can't be null","messagePattern":"baseDir can't be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java","lineNumber":59,"sourceCode":"\n    private Position lastPosition = new Position();\n\n    /**\n     * @param baseDir      metric文件所在目录\n     * @param baseFileName metric文件名的关键字，比如 alihot-metrics.log\n     */\n    public MetricSearcher(String baseDir, String baseFileName) {\n        this(baseDir, baseFileName, defaultCharset);\n    }\n\n    /**\n     * @param baseDir      metric文件所在目录\n     * @param baseFileName metric文件名的关键字，比如 alihot-metrics.log\n     * @param charset\n     */\n    public MetricSearcher(String baseDir, String baseFileName, Charset charset) {\n        if (baseDir == null) {\n            throw new IllegalArgumentException(\"baseDir can't be null\");\n        }\n        if (baseFileName == null) {\n            throw new IllegalArgumentException(\"baseFileName can't be null\");\n        }\n        if (charset == null) {\n            throw new IllegalArgumentException(\"charset can't be null\");\n        }\n        this.baseDir = baseDir;\n        if (!baseDir.endsWith(File.separator)) {\n            this.baseDir += File.separator;\n        }\n        this.baseFileName = baseFileName;\n        metricsReader = new MetricsReader(charset);\n    }\n\n    /**\n     * 从beginTime开始，检索recommendLines条(大概)记录。同一秒中的数据是原子的，不能分割成多次查询。\n     *","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java#L41-L77","documentation":"MetricSearcher scans historical metric log files under baseDir for records matching baseFileName. The directory argument is mandatory; a null baseDir throws IllegalArgumentException because there is no sane default location for metric files and file listing would NPE later.","triggerScenarios":"new MetricSearcher(null, baseFileName) or new MetricSearcher(null, baseFileName, charset), i.e. any of the three constructors invoked with a null first argument.","commonSituations":"Building MetricSearcher from configuration where the metric directory property was never set (e.g. sentinel-dashboard reading a missing cigar/metric dir), or refactoring code that previously derived baseDir from a possibly-null variable.","solutions":["Pass the actual metric log directory, typically the same dir configured for MetricWriter, e.g. ${user.home}/logs/csp/.","If the dir comes from a property, ensure it is set before constructing the searcher (check RecordLog configuration / SentinelConfig).","Guard with a null check and fall back to the default log dir (MetricWriterLogBaseDir) instead of null."],"exampleFix":"// before\nnew MetricSearcher(nullMetricDir, \"sentinel-dashboard-metrics.log\");\n\n// after\nString baseDir = metricDir != null ? metricDir : MetricWriter.getBaseDir();\nnew MetricSearcher(baseDir, \"sentinel-dashboard-metrics.log\");","handlingStrategy":"validation","validationCode":"String baseDir = Objects.requireNonNullElse(config.getMetricDir(),\n    MetricWriter.getBaseDir()); // known metric log dir\nnew MetricSearcher(baseDir, \"appName-metrics.log\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize metric dir resolution in one helper that never returns null.","Wire the searcher to the same directory property MetricWriter uses."],"tags":["sentinel","metrics","search","constructor-validation","filesystem"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}