{"record":{"id":"9260ad2ea71344bd","repo":"nathanmarz/storm","slug":"the-same-metric-name-name-was-registered-twice","errorCode":null,"errorMessage":"The same metric name `${name}` was registered twice.","messagePattern":"The same metric name `(.+?)` was registered twice\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/backtype/storm/task/TopologyContext.java","lineNumber":246,"sourceCode":"    public <T extends IMetric> T registerMetric(String name, T metric, int timeBucketSizeInSecs) {\n        if((Boolean)_openOrPrepareWasCalled.deref() == true) {\n            throw new RuntimeException(\"TopologyContext.registerMetric can only be called from within overridden \" + \n                                       \"IBolt::prepare() or ISpout::open() method.\");\n        }\n        \n        Map m1 = _registeredMetrics;\n        if(!m1.containsKey(timeBucketSizeInSecs)) {\n            m1.put(timeBucketSizeInSecs, new HashMap());\n        }\n\n        Map m2 = (Map)m1.get(timeBucketSizeInSecs);\n        if(!m2.containsKey(_taskId)) {\n            m2.put(_taskId, new HashMap());\n        }\n\n        Map m3 = (Map)m2.get(_taskId);\n        if(m3.containsKey(name)) {\n            throw new RuntimeException(\"The same metric name `\" + name + \"` was registered twice.\" );\n        } else {\n            m3.put(name, metric);\n        }\n\n        return metric;\n    }\n\n    /*\n     * Convinience method for registering ReducedMetric.\n     */\n    public ReducedMetric registerMetric(String name, IReducer reducer, int timeBucketSizeInSecs) {\n        return registerMetric(name, new ReducedMetric(reducer), timeBucketSizeInSecs);\n    }\n    /*\n     * Convinience method for registering CombinedMetric.\n     */\n    public CombinedMetric registerMetric(String name, ICombiner combiner, int timeBucketSizeInSecs) {\n        return registerMetric(name, new CombinedMetric(combiner), timeBucketSizeInSecs);","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/backtype/storm/task/TopologyContext.java#L228-L264","documentation":"registerMetric stores metrics per time-bucket and per task id, and each metric name must be unique within a task. Registering two metrics with the same name for the same task throws this RuntimeException to prevent silent metric collision/overwriting in the metrics consumers.","triggerScenarios":"Calling registerMetric twice with the same name string within the same task — e.g. registering \"request-count\" in both prepare and a helper method, or in a loop that re-registers on each execution.","commonSituations":"Copy-pasted metric registration code with duplicated names, metrics registered once per element/component in a loop when they should be registered once, re-preparing bolts with shared registration logic that isn't idempotent.","solutions":["Use unique, descriptive names for every metric (e.g. prefix with component/purpose).","Guard registration with a flag or check so it executes exactly once per task.","Differentiate metrics registered in loops by appending the loop key to the name.","On re-prepare (e.g. after reload), skip registration if the metric already exists — reuse the instance."],"exampleFix":"// before\ncontext.registerMetric(\"count\", new CountMetric(), 10);\n// later, same task:\ncontext.registerMetric(\"count\", new CountMetric(), 10); // throws\n\n// after\ncontext.registerMetric(\"spout-emit-count\", new CountMetric(), 10);\ncontext.registerMetric(\"bolt-ack-count\", new CountMetric(), 10);","handlingStrategy":"validation","validationCode":"Set<String> registered = new HashSet<>();\nboolean safe = registered.add(\"my-metric-name\"); // only call registerMetric if safe==true","typeGuard":null,"tryCatchPattern":"try {\n    context.registerMetric(name, metric, interval);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"registered twice\")) {\n        LOG.warn(\"metric {} already registered; reusing\", name);\n    } else { throw e; }\n}","preventionTips":["Keep a single registration method per component that runs once.","Prefix metric names with component/role to guarantee uniqueness.","Never register metrics inside loops without appending a unique key.","Track registered names in a Set and check before calling registerMetric."],"tags":["storm","metrics","naming","duplicate"],"backgroundTag":"file-already-exists","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}