{"record":{"id":"7c199a09e216b367","repo":"prestodb/presto","slug":"node-ttl-fetcher-factory-s-is-already-registere","errorCode":null,"errorMessage":"Node ttl fetcher factory '%s' is already registered","messagePattern":"Node ttl fetcher factory '(.+?)' is already registered","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/ttl/nodettlfetchermanagers/ConfidenceBasedNodeTtlFetcherManager.java","lineNumber":171,"sourceCode":"\n    public Optional<NodeTtl> getTtlInfo(InternalNode node)\n    {\n        return nodeTtlMap.containsKey(node) ? Optional.of(nodeTtlMap.get(node)) : Optional.empty();\n    }\n\n    @Override\n    public Map<InternalNode, NodeTtl> getAllTtls()\n    {\n        return ImmutableMap.copyOf(nodeTtlMap);\n    }\n\n    @Override\n    public void addNodeTtlFetcherFactory(NodeTtlFetcherFactory nodeTtlFetcherFactory)\n    {\n        requireNonNull(nodeTtlFetcherFactory, \"nodeTtlFetcherFactory is null\");\n\n        if (ttlFetcherFactories.putIfAbsent(nodeTtlFetcherFactory.getName(), nodeTtlFetcherFactory) != null) {\n            throw new IllegalArgumentException(format(\"Node ttl fetcher factory '%s' is already registered\", nodeTtlFetcherFactory.getName()));\n        }\n    }\n\n    @Override\n    public void loadNodeTtlFetcher()\n            throws Exception\n    {\n        String factoryName = \"infinite\";\n        Map<String, String> properties = ImmutableMap.of();\n\n        if (Files.exists(TTL_FETCHER_CONFIG)) {\n            properties = new HashMap<>(loadProperties(TTL_FETCHER_CONFIG.toFile()));\n            factoryName = properties.remove(TTL_FETCHER_PROPERTY_NAME);\n\n            checkArgument(!isNullOrEmpty(factoryName),\n                    \"Node ttl fetcher configuration %s does not contain %s\", TTL_FETCHER_CONFIG.toAbsolutePath(), TTL_FETCHER_PROPERTY_NAME);\n        }\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/ttl/nodettlfetchermanagers/ConfidenceBasedNodeTtlFetcherManager.java#L153-L189","documentation":"ConfidenceBasedNodeTtlFetcherManager.addNodeTtlFetcherFactory throws IllegalArgumentException when a NodeTtlFetcherFactory with a name already present in ttlFetcherFactories is registered (putIfAbsent returns non-null). Each node TTL fetcher factory must have a unique name within the manager.","triggerScenarios":"Calling addNodeTtlFetcherFactory with a factory whose getName() is already registered — duplicate plugin load, two plugins shipping the same fetcher factory name, or repeated setup() invocations on the same manager instance (noted by its callers testTtlAwareScheduling and setup).","commonSituations":"Duplicate node-ttl plugin jars deployed to workers; two TTL plugins colliding on factory name; tests calling setup twice; hot plugin reload re-registering the same factory.","solutions":["Deduplicate plugin jars / ensure only one plugin registers the fetcher factory.","Give one of the colliding factories a unique getName().","Instantiate a new ConfidenceBasedNodeTtlFetcherManager instead of re-registering into an existing one.","Wrap registration in a contains-check or try-catch to make setup idempotent in tests."],"exampleFix":"// before\nnodeTtlFetcherManager.addNodeTtlFetcherFactory(new JmxNodeTtlFetcherFactory(\"jmx\"));\nnodeTtlFetcherManager.addNodeTtlFetcherFactory(new JmxNodeTtlFetcherFactory(\"jmx\")); // throws\n\n// after\nNodeTtlFetcherFactory factory = new JmxNodeTtlFetcherFactory(\"jmx\");\ntry {\n    nodeTtlFetcherManager.addNodeTtlFetcherFactory(factory);\n} catch (IllegalArgumentException e) {\n    // already registered — skip\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the fetcher factory name is not already present before registering\nboolean exists = nodeTtlFetcherManager.getNodeTtlFetcherFactories().stream()\n    .anyMatch(f -> f.getName().equals(factory.getName()));\nif (!exists) {\n    nodeTtlFetcherManager.addNodeTtlFetcherFactory(factory);\n}","typeGuard":"boolean isFetcherNameFree(ConfidenceBasedNodeTtlFetcherManager m, String name) {\n    return m.getNodeTtlFetcherFactories().stream().noneMatch(f -> f.getName().equals(name));\n}","tryCatchPattern":"try {\n    nodeTtlFetcherManager.addNodeTtlFetcherFactory(factory);\n} catch (IllegalArgumentException e) {\n    LOG.warn(\"Node ttl fetcher factory '%s' already registered; skipping\", factory.getName());\n}","preventionTips":["Deduplicate node-ttl plugin deployments across workers.","Give each NodeTtlFetcherFactory a unique getName().","Avoid calling setup() twice against the same manager instance in tests.","Wrap factory registration to be idempotent for reload scenarios."],"tags":["duplicate-registration","ttl","plugin","presto"],"backgroundTag":"duplicate-factory-registration","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}