Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/tumblr.py (Python)

Code before:
                self._download_json(
                    f'https://www.tumblr.com/api/v2/blog/{blog}/posts/{video_id}/permalink',
                    video_id, headers={'Authorization': f'Bearer {self._ACCESS_TOKEN}'}, fatal=False),
                ('response', 'timeline', 'elements', 0, {dict})) or {}
        content_json = traverse_obj(post_json, ((('trail', 0), None), 'content', ..., {dict}))

        # the url we're extracting from might be an original post or it might be a reblog.
        # if it's a reblog, og:description will be the reblogger's comment, not the uploader's.
        # content_json is always the op, so if it exists but has no text, there's no description
        if content_json:
            description = '\n\n'.join(
                item.get('text') for item in content_json if item.get('type') == 'text') or None
        else:
            description = self._og_search_description(webpage, default=None)
        uploader_id = traverse_obj(post_json, 'reblogged_root_name', 'blog_name')

        info_dict = {
            'id': video_id,
            'title': post_json.get('summary') or (blog if api_only else self._html_search_regex(
                r'(?s)<title>(?P<title>.*?)(?: \| Tumblr)?</title>', webpage, 'title', default=blog)),
            'description': description,
            'timestamp':
                traverse_obj(post_json,
                             ('trail', 0, 'post', 'timestamp'),  # Oldest post in reblog chain
                             'timestamp',  # Timestamp of the post itself
                             expected_type=int),
            'uploader_id': uploader_id,
            'uploader_url': f'https://{uploader_id}.tumblr.com/' if uploader_id else None,
            **traverse_obj(post_json, {
                'like_count': ('like_count', {int_or_none}),
                'repost_count': ('reblog_count', {int_or_none}),
                'tags': ('tags', ..., {str}),
            }),
            'age_limit': {True: 18, False: 0}.get(post_json.get('is_nsfw')),
        }

        # for tumblr's own video hosting
        fallback_format = None
        formats = []
        video_url = self._og_search_video_url(webpage, default=None)
        # for external video hosts
        entries = []
        ignored_providers = set()
        unknown_providers = set()

        for video_json in traverse_obj(content_json, lambda _, v: v['type'] in ('video', 'audio')):
            media_json = video_json.get('media') or {}
            if api_only and not media_json.get('url') and not video_json.get('url'):
                raise ExtractorError('Failed to find video data for dashboard-only post')
            provider = video_json.get('provider')


Review comment (suggestion):
```suggestion
            'timestamp': traverse_obj(
                post_json,
                ('trail', 0, 'post', 'timestamp'),  # Oldest post in reblog chain
                'timestamp',                        # Timestamp of the post itself
                expected_type=int_or_none),
```

Code after:
                self._download_json(
                    f'https://www.tumblr.com/api/v2/blog/{blog}/posts/{video_id}/permalink',
                    video_id, headers={'Authorization': f'Bearer {self._ACCESS_TOKEN}'}, fatal=False),
                ('response', 'timeline', 'elements', 0, {dict})) or {}
        content_json = traverse_obj(post_json, ((('trail', 0), None), 'content', ..., {dict}))

        # the url we're extracting from might be an original post or it might be a reblog.
        # if it's a reblog, og:description will be the reblogger's comment, not the uploader's.
        # content_json is always the op, so if it exists but has no text, there's no description
        if content_json:
            description = '\n\n'.join(
                item.get('text') for item in content_json if item.get('type') == 'text') or None
        else:
            description = self._og_search_description(webpage, default=None)
        uploader_id = traverse_obj(post_json, 'reblogged_root_name', 'blog_name')

        info_dict = {
            'id': video_id,
            'title': post_json.get('summary') or (blog if api_only else self._html_search_regex(
                r'(?s)<title>(?P<title>.*?)(?: \| Tumblr)?</title>', webpage, 'title', default=blog)),
            'description': description,
            'uploader_id': uploader_id,
            'uploader_url': f'https://{uploader_id}.tumblr.com/' if uploader_id else None,
            **traverse_obj(post_json, {
                # Try oldest post in reblog chain, fall back to timestamp of the post itself
                'timestamp': ((('trail', 0, 'post'), None), 'timestamp', {int_or_none}, any),
                'like_count': ('like_count', {int_or_none}),
                'repost_count': ('reblog_count', {int_or_none}),
                'tags': ('tags', ..., {str}),
            }),
            'age_limit': {True: 18, False: 0}.get(post_json.get('is_nsfw')),
        }

        # for tumblr's own video hosting
        fallback_format = None
        formats = []
        video_url = self._og_search_video_url(webpage, default=None)
        # for external video hosts
        entries = []
        ignored_providers = set()
        unknown_providers = set()

        for video_json in traverse_obj(content_json, lambda _, v: v['type'] in ('video', 'audio')):
            media_json = video_json.get('media') or {}
            if api_only and not media_json.get('url') and not video_json.get('url'):
                raise ExtractorError('Failed to find video data for dashboard-only post')
            provider = video_json.get('provider')

            if provider in ('tumblr', None):
                fallback_format = {
                    'url': media_json.get('url') or video_url,