unfurl icon indicating copy to clipboard operation
unfurl copied to clipboard

Possible JSON parser issue with nested data or when key contains multiple values

Open mattkoester opened this issue 7 months ago • 2 comments

I'm sorry in advance if I'm using any incorrect terminology—I'm just starting to learn about JSON and how Unfurl works, and the "issue" may be with my understanding rather than Unfurl itself. I'm not even sure this relates to the JSON parser. 😂

Description/Context

I noticed what might be an inconsistency with the JSON parser while examining a YouTube link. When viewing the list of one's own videos in YouTube Studio, a filter bar is provided so videos can be filtered based on properties such as their visibility (e.g. Public, Private, Draft, etc.), whether they have a copyright claim, and so on:

Image

I added a few of these filters and sorted the list by date, and then I used Unfurl to examine the resulting URL. Unfurl was able to parse the sort portion of the URL but did not seem to parse the filter portion (see example below).

Example

This example YouTube link shows the behavior I'm describing (note: I replaced my YouTube channel ID in this example with the Apple TV YouTube channel ID for privacy): https://studio.youtube.com/channel/UC1Myj674wRVXB9I4c6Hm5zA/videos/upload?o=U&filter=%5B%7B%22name%22%3A%22VISIBILITY%22%2C%22value%22%3A%5B%22PUBLIC%22%2C%22UNLISTED%22%5D%7D%2C%7B%22name%22%3A%22HAS_COPYRIGHT_CLAIM%22%2C%22value%22%3A%22VIDEO_HAS_COPYRIGHT_CLAIM%22%7D%5D&sort=%7B%22columnType%22%3A%22date%22%2C%22sortOrder%22%3A%22DESCENDING%22%7D

When I examine the URL in Unfurl, it parses the sort portion of the URL into the two separate key-value pairs, but it doesn't seem to parse the filter portion.

Image

I formatted just the sort and filter parts to try to understand what's happening:

Sort:

{
    "columnType": "date",
    "sortOrder": "DESCENDING"
}

Filter:

[
    {
        "name": "VISIBILITY",
        "value": [
            "PUBLIC",
            "UNLISTED"
        ]
    },
    {
        "name": "HAS_COPYRIGHT_CLAIM",
        "value": "VIDEO_HAS_COPYRIGHT_CLAIM"
    }
]

The main differences I noticed are:

  1. The filter information has more levels of nesting than the sort info.
  2. One of the keys in the filter portion has an array (I think?) of two values (["PUBLIC","UNLISTED"]), whereas the key-value pairs in the sort portion only have single values.
  3. I'm not sure how to phrase this when discussing JSON, but the key names and values in the filter portion are explicitly referred to as "name": and "value":, whereas the key names and values in the sort section seem to be entered in a "shorthand" way (sort of like how one can write padding: 10px 20px; in CSS instead of padding-top: 10px; padding-right: 20px; padding-bottom: 10px; padding-left: 20px;.

I don't know enough about JSON and Unfurl to feel confident that this is actually an inconsistency, but I wanted to report it just in case. Also, I'm sorry again if I've used the wrong terminology or made any other mistakes in this post. I hope it makes sense overall! And thank you for Unfurl!

mattkoester avatar Apr 10 '25 17:04 mattkoester

Hi Matt! I'm very sorry for the long delay before responding; thanks so much for being interested in Unfurl and reporting an issue! Let me take a look.

obsidianforensics avatar May 20 '25 16:05 obsidianforensics

No worries at all, and thank you for taking a look!

mattkoester avatar May 20 '25 16:05 mattkoester

Hey Matt, thanks again for creating the issue. For this bug, the relevant difference between Sort and Filter in your example was that the Filter value was a list, while the Sort value was a dict. Unfurl wasn't parsing lists as JSON if the list was at the top-level.

I've fixed the issue, and also added some updates for readability to the JSON parser (just showing the count of items in intermediate steps): Image

obsidianforensics avatar Aug 26 '25 03:08 obsidianforensics

Hi Ryan, that's great! Thanks for looking into the issue and figuring out a solution!

mattkoester avatar Oct 15 '25 16:10 mattkoester