@param uid the id of the add-on (e.g. “binding-dmx”, “json:transform-format” or “marketplace:123456”)
@param uid the technical name of the add-on (e.g. “influxdb”)
In addition it is not clear what purpose the uid and id serve, why both uid and id are necessary, what problems will happen if uid or id are set in a wrong way. The text is not clear: if the uid is “the id of the addon”, then what is the id parameter for?
It could be that part of the trouble comes from how marketplace support started, and it started from community forums. @J-N-K eventually brought concept of 3rd party extensions through json file/uri which in some extent must comply with a first concept. I agree it is misleading as UID should be really assigned by OH core by tracking (or assigning) marketplace an identifier. At the same time, if UID is assigned by OH it may not be reproducible over updates, hence relying on settings/uris and publisher controlled UID allows to keep it under publisher control.
To be fair - I don’t know for real, but most of elements within OH will have UID (Binding, Thing, Channel, Item, Link, Sitemap etc.), so third party extension is no exception there. The only difference is - nobody tracks marketplace ID and addon provisioned through it.
If a json distribution file includes addons without ID, as at https://ohaddons.bapha.be/uidtestsjar1/, then all addon services return zero addons, and openhab.log gets:
2026-09-29 11:28:33.710 [ERROR] [place.internal.json.JsonAddonService] - bundle org.openhab.core.addon.marketplace:5.2.1 (158)[org.openhab.core.addon.marketplace.internal.json.JsonAddonService(52)] : The modified method has thrown an exception
java.lang.IllegalArgumentException: id must not be empty
at org.openhab.core.addon.Addon.<init>(Addon.java:100)
at org.openhab.core.addon.Addon$Builder.build(Addon.java:480)
at org.openhab.core.addon.marketplace.internal.json.JsonAddonService.fromAddonEntry(JsonAddonService.java:214)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
…
2026-09-29 11:28:34.215 [ERROR] [rg.apache.cxf.jaxrs.utils.JAXRSUtils] - Problem with writing the data, class org.openhab.core.io.rest.Stream2JSONInputStream, ContentType: application/json
Do market places have to announce an ID for a binding add-on, that has be identical as in OH-INF/addon/addon.xml:<addon:addon id="**HERE?**" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"…?
openhab> addons info marketplace marketplace:167392
Type binding
UID marketplace:167392
ID voltronic
Label Voltronic Inverters Binding [4.3; 6.0)
Link https://community.openhab.org/t/167392
Compatible true
Content Type application/vnd.openhab.bundle
Properties:
jar_download_url: https://github.com/dilyanpalauzov/voltronic-openhab/releases/download/20260912/be.bapha.openhab.binding.voltronic-4.3.0.jar
How does Discord/openHAB determine the ID of the add-on?
The add-on JSON file https://ohaddons.bapha.be/samesame/ utilizes the same add-on twice . The json file contains once uid: gggggg-uid-1, id: gggggg-id-1, and once gggggg-uid-2, id:voltronic, otherwise both entries are identical.
When I install the binding from the market, then under Main UI → Settings → Things I can add a new thing for (binding)marketplaced:167392 Voltronic Inverter Binding [4.3; 6.0) → (Add Manually) voltronic:inverter Voltronic Inverter → …
When I uninstall the binding from the market place, and install the “Voltronic Binding (JAR as on marketplace, id: voltronic)” binding, I can likewise add a thing.
When I uninstall that binding, and install the id: gggggg-id-1 add-on, then under Settings → Things I can select (Choose Binding)json:ggggg-id-1 Voltronic Binding (JAR as marketplace, id: ggggg-id-1) → and here I see the message “No thing types can be added with this binding.”
This is how CommunityMarketplaceAddonService.java obtains the IDs of the addons over getAddon(String uid, Locale locale) → convertTopicToAddon():
For a topic with number K, so an addon with UID marketplace:K, openHAB downloads, \https://community.openhab.org/t/K.json, then iterates over all links in Discord, and if a link ends with .kar or .jar, then Add-on id = determineIdFromUrl(postLink.url), so:
static String determineIdFromUrl(String url) {
Matcher matcher = Pattern.compile(".*/(.*?)-\\d+\\.\\d+\\.\\d+.*").matcher(url);
if (matcher.matches()) {
String bundleName = matcher.group(1);
return bundleName.substring(bundleName.lastIndexOf(".") + 1);
}
System.err.println("Could not determine bundle name from url: " + url);
return null;
}
Thus for the market place to work, apparently the id in OH-INF/addon/addon.xml:<addon:addon id="HERE" … must coincide with the last word in the URI, which follows a dot and precedes a dash and three dot-separated numbers.
I think now the same CommunityMarketplaceAddonService.convertTopicToAddon() could extract in the same way a version from the URL, as done in determineIdFromUrl and then pass it to Addon.Builder builder = Addon.create(uid).withVersion(…)
Indeed, it is important and starting from later releases of OH 4.x the addon id (earlier binding id) is validated more strictly. I recall that at some point thing types started to be validated against addon provider forcing a close relation between filename and UID segment. I can’t identify exact code which does that right now, neither I am not sure if its still a case, but I remember its needs to be 1:1.