# getFullPath is null for NodeDescription

**URL:** <https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922>\
**Category:** Module Development\
**Tags:** ignition81\
**Created:** [June 2, 2025, 9:40pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922 "2025-06-02T21:40:12Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zhou\_Zeng](https://avatars.discourse-cdn.com/v4/letter/z/c37758/32.png) [@Zhou\_Zeng](https://forum.inductiveautomation.com/u/Zhou_Zeng)\
**Post date:** [June 2, 2025, 9:40pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/1 "2025-06-02T21:40:12Z")

</div>

i tried calling getFullPath from a NodeDescription object, but it returns null. Does anyone know if I am doing something wrong here?

```python
Results<NodeDescription> browseResults = context.getTagManager().browseAsync(tagPath, browseFilter, securityContext).get();
Collection<NodeDescription> tagDescriptions = browseResults.getResults();
if (tagDescriptions != null) {
    for (NodeDescription tagDesc : tagDescriptions) {
        // this line will throw null pointer error
        logger.log(tagDesc.getFullPath().toString());

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 2, 2025, 10:01pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/2 "2025-06-02T22:01:19Z")

</div>

Can you provide the exact stack trace? What are you ultimately trying to do?

At a glance your code looks okay. Where are you running it?

---

<div class="post-metadata">

**Author:** ![Zhou\_Zeng](https://avatars.discourse-cdn.com/v4/letter/z/c37758/32.png) [@Zhou\_Zeng](https://forum.inductiveautomation.com/u/Zhou_Zeng)\
**Post date:** [June 2, 2025, 11:34pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/3 "2025-06-02T23:34:04Z")

</div>

Sure thing, at the bottom is the stack trace. Ultimately, I am adding a feature to the [ignition NodeRed module](https://github.com/IgnitionModuleDevelopmentCommunity/IgnitionNode-RED) to allow browsing tags with a browseFilter through http post call. I am running it inside an Ignition Gateway (v8.1.43). And below is the actual code that produces this exception.

```java
        // Create browse filter
        BrowseFilter browseFilter = createBrowseFilter(browseFilterJson);

        Results<NodeDescription> browseResults = context.getTagManager().browseAsync(tagPath, browseFilter, securityContext).get();
        Collection<NodeDescription> tagDescriptions = browseResults.getResults();
        if (tagDescriptions != null) {
            for (NodeDescription tagDesc : tagDescriptions) {
                JSONObject tagObject = new JSONObject();
                tagObject.put("name", tagDesc.getName());
                // todo: tagDesc.getFullPath() returns null for some tags, need to handle this case
                tagObject.put("tagPath", tagDesc.getFullPath().toString());

```

and here is the stack trace

```python
java.lang.NullPointerException: Cannot invoke "Object.toString()" because the return value of "com.inductiveautomation.ignition.common.tags.browsing.NodeDescription.getFullPath()" is null

at org.imdc.nodered.servlet.TagCommandHandler.browseTags(TagCommandHandler.java:120)

at org.imdc.nodered.servlet.TagCommandHandler.handleTagBrowse(TagCommandHandler.java:89)

at org.imdc.nodered.servlet.NodeREDServlet.doPost(NodeREDServlet.java:166)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:523)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)

at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:86)

at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)

at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)

at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.Server.handle(Server.java:563)

at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)

at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)

at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)

at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)

at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:558)

at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:379)

at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:146)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)

at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)

at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 3, 2025, 2:43pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/4 "2025-06-03T14:43:59Z")

</div>

What's the tagpath you're passing in? Is it fully qualified, including a provider name?

---

<div class="post-metadata">

**Author:** ![Zhou\_Zeng](https://avatars.discourse-cdn.com/v4/letter/z/c37758/32.png) [@Zhou\_Zeng](https://forum.inductiveautomation.com/u/Zhou_Zeng)\
**Post date:** [June 4, 2025, 12:16pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/5 "2025-06-04T12:16:23Z")

</div>

my apology, i usually get a notification when someone replies, but this time I didn't.  
I am not sure if it is, but here is the line of code that constructs the tagPath and it looks like would have a provider.

```java
TagPath tagPath = TagPathParser.parseSafe(defaultTagProvider, tagPathStr);

```

should I do it in a different way? this was the original code from the module repo

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 4, 2025, 3:31pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/6 "2025-06-04T15:31:07Z")

</div>

🤷‍♂️

This particular area is very complicated -- browse at the tag manager level gets indirected into particular tag providers, then depending on the tag provider gets indirected into a particular `BrowsableNode`, and then that particular `BrowsableNode` will have different behavior depending on exactly what type of tag it is (i.e. udt definition vs instance vs folder vs regular tag).

So it seems like it might be entirely legitimate to have a null full path depending on what path you're actually browsing, but it's also possible there's something else wrong in this example that I'm not seeing. Unfortunately I'm not versed enough in the tag system to say for sure.

---

<div class="post-metadata">

**Author:** ![Zhou\_Zeng](https://avatars.discourse-cdn.com/v4/letter/z/c37758/32.png) [@Zhou\_Zeng](https://forum.inductiveautomation.com/u/Zhou_Zeng)\
**Post date:** [June 4, 2025, 3:52pm UTC](https://forum.inductiveautomation.com/t/getfullpath-is-null-for-nodedescription/106922/7 "2025-06-04T15:52:33Z")

</div>

gotcha, I figured I would just not rely on getFullPath and build the fullPath based on tagName and tagPath instead. But then it would not produce the correct fullPath with recursive browseFilter, so I ended up having to write my own browse function to support recursive browsing while getting the full path.

I am sharing my working function below. it works, but maybe there is a better way to do this.

```java
    private Collection<NodeBrowseInfo> browseTagsHelper(TagPath tagPath, SecurityContext securityContext, BrowseFilter browseFilter) throws ExecutionException, InterruptedException {

        boolean recursive = browseFilter.isRecursive();
        Results<NodeDescription> browseResults = context.getTagManager().browseAsync(tagPath, BrowseFilter.NONE, securityContext).get();

        Collection<NodeDescription> nodeDescriptions = browseResults.getResults();
        if (nodeDescriptions == null || nodeDescriptions.isEmpty()) return null;

        Collection<NodeBrowseInfo> nodeBrowseInfos = new ArrayList<>();
        for(NodeDescription node: nodeDescriptions) {
            TagPath fullPath = tagPath.getChildPath(node.getName());
            if (browseFilter.checkProperties(node) && browseFilter.checkNameFilters(fullPath)) {
                // If the node matches the filter, add it to the results
                nodeBrowseInfos.add(new NodeBrowseInfo(fullPath, node));
            }

            if (recursive && node.hasChildren() && node.getDataType() != DataType.Document) {
                // If the node is a folder and recursion is enabled, browse it recursively
                Collection<NodeBrowseInfo> childResults = browseTagsHelper(fullPath, securityContext, browseFilter);
                if (childResults != null) {
                    nodeBrowseInfos.addAll(childResults);
                }
            }
        }

        return nodeBrowseInfos;
    }

```
