[GH-ISSUE #85] Validation errors for PresenceItem #3

Closed
opened 2026-02-28 01:19:06 +03:00 by kerem · 3 comments
Owner

Originally created by @tomballgithub on GitHub (Jan 21, 2026).
Original GitHub issue: https://github.com/tr4nt0r/python-xbox/issues/85

I am using a script that relies on 'xbox-webapi-python', but I noticed that your fork is actually maintained, so I thought I'd bring my issue here.

The issue is that within pythonxbox\api\provider\presence\__init__.py, I am getting errors, even with your code base, of:
1 validation error for PresenceItem devices.0.titles.1.activity Input should be a valid array [type=list_type, input_value={'richPresence': 'The City: The Theater'}, input_type=dict] For further information visit https://errors.pydantic.dev/2.12/v/list_type

The line that causes the issues is the last one in get_presence:
return PresenceItem.model_validate_json(resp.text)

I noticed that the response from Xbox does not give an error when it's like this:

{
    'xuid': '2535468411947698',
    'state': 'Online',
    'devices': [{
            'type': 'Scarlett',
            'titles': [{
                    'id': '750323071',
                    'name': 'Home',
                    'placement': 'Background',
                    'state': 'Active',
                    'lastModified': '2026-01-20T22:32:36.7770783'
                }, {
                    'id': '1870487792',
                    'name': 'NBA 2K26',
                    'placement': 'Full',
                    'state': 'Active',
                    'lastModified': '2026-01-20T22:32:36.7770783'
                }
            ]
        }
    ]
}

but it does give an error when it's this:

{
    'xuid': '2535468411947698',
    'state': 'Online',
    'devices': [{
            'type': 'Scarlett',
            'titles': [{
                    'id': '750323071',
                    'name': 'Home',
                    'placement': 'Background',
                    'state': 'Active',
                    'lastModified': '2026-01-20T22:32:36.7770783'
                }, {
                    'id': '1870487792',
                    'activity': {
                        'richPresence': 'The City'
                    },
                    'name': 'NBA 2K26',
                    'placement': 'Full',
                    'state': 'Active',
                    'lastModified': '2026-01-20T22:33:22.3885066'
                }
            ]
        }
    ]
}

The part that is causing the error is this:
'activity': { 'richPresence': 'The City' },

And if I change the last line to the following, removing the 'activity' section, it no longer fails:

        data = resp.json()
        # Iterate through each device
        for device in data.get('devices', []):
            # Iterate through each title in that device
            for title in device.get('titles', []):
                # Remove 'activity' if it exists
                title.pop('activity', None)
        json_string = json.dumps(data)
        return PresenceItem.model_validate_json(json_string)

This page from Microsoft shows a sample PresenceRecord response that includes the 'activity' section:
https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/uri/presence/uri-usersmeget

And if I force that exact response into get_presence as follows, it also generates errors for the 'activity' section:

        json_string = """
        {
          "xuid": "0123456789",
          "state": "online",
          "devices": [
            {
              "type": "D",
              "titles": [
                {
                  "id": "12341234",
                  "name": "Contoso 5",
                  "state": "active",
                  "placement": "fill",
                  "timestamp": "2012-09-17T07:15:23.4930000",
                  "activity": {
                    "richPresence": "Team Deathmatch on Nirvana"
                  }
                },
                {
                  "id": "12341235",
                  "name": "Contoso Waypoint",
                  "timestamp": "2012-09-17T07:15:23.4930000",
                  "placement": "snapped",
                  "state": "active",
                  "activity": {
                    "richPresence": "Using radar"
                  }
                }
              ]
            },
            {
              "type": "W8",
              "titles": [
                {
                  "id": "23452345",
                  "name": "Contoso Gamehelp",
                  "state": "active",
                  "placement": "full",
                  "timestamp": "2012-09-17T07:15:23.4930000",
                  "activity": {
                    "richPresence": "Nirvana page"
                  }
                }
              ]
            }
          ]
        }
        """
        return PresenceItem.model_validate_json(json_string)

The errors:

3 validation errors for PresenceItem
devices.0.titles.0.activity
  Input should be a valid array [type=list_type, input_value={'richPresence': 'Team Deathmatch on Nirvana'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.12/v/list_type
devices.0.titles.1.activity
  Input should be a valid array [type=list_type, input_value={'richPresence': 'Using radar'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.12/v/list_type
devices.1.titles.0.activity
  Input should be a valid array [type=list_type, input_value={'richPresence': 'Nirvana page'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.12/v/list_type

And these errors are pydantic not liking something about what should be a valid JSON from Xbox.

How to formally solve?
@tr4nt0r


This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting /reward 100 (replace 100 with the amount).
🕵️‍♂️ If someone starts working on this issue to earn the rewards, they can comment /try to let everyone know!
🙌 And when they open the PR, they can comment /claim #85 either in the PR description or in a PR's comment.

🪙 Also, everyone can tip any user commenting /tip 20 @tomballgithub (replace 20 with the amount, and @tomballgithub with the user to tip).

📖 If you want to learn more, check out our documentation.
Originally created by @tomballgithub on GitHub (Jan 21, 2026). Original GitHub issue: https://github.com/tr4nt0r/python-xbox/issues/85 I am using a script that relies on 'xbox-webapi-python', but I noticed that your fork is actually maintained, so I thought I'd bring my issue here. The issue is that within` pythonxbox\api\provider\presence\__init__.py`, I am getting errors, even with your code base, of: `1 validation error for PresenceItem devices.0.titles.1.activity Input should be a valid array [type=list_type, input_value={'richPresence': 'The City: The Theater'}, input_type=dict] For further information visit https://errors.pydantic.dev/2.12/v/list_type` The line that causes the issues is the last one in `get_presence`: `return PresenceItem.model_validate_json(resp.text)` I noticed that the response from Xbox does not give an error when it's like this: ``` { 'xuid': '2535468411947698', 'state': 'Online', 'devices': [{ 'type': 'Scarlett', 'titles': [{ 'id': '750323071', 'name': 'Home', 'placement': 'Background', 'state': 'Active', 'lastModified': '2026-01-20T22:32:36.7770783' }, { 'id': '1870487792', 'name': 'NBA 2K26', 'placement': 'Full', 'state': 'Active', 'lastModified': '2026-01-20T22:32:36.7770783' } ] } ] } ``` but it does give an error when it's this: ``` { 'xuid': '2535468411947698', 'state': 'Online', 'devices': [{ 'type': 'Scarlett', 'titles': [{ 'id': '750323071', 'name': 'Home', 'placement': 'Background', 'state': 'Active', 'lastModified': '2026-01-20T22:32:36.7770783' }, { 'id': '1870487792', 'activity': { 'richPresence': 'The City' }, 'name': 'NBA 2K26', 'placement': 'Full', 'state': 'Active', 'lastModified': '2026-01-20T22:33:22.3885066' } ] } ] } ``` The part that is causing the error is this: `'activity': { 'richPresence': 'The City' },` And if I change the last line to the following, removing the 'activity' section, it no longer fails: ``` data = resp.json() # Iterate through each device for device in data.get('devices', []): # Iterate through each title in that device for title in device.get('titles', []): # Remove 'activity' if it exists title.pop('activity', None) json_string = json.dumps(data) return PresenceItem.model_validate_json(json_string) ``` This page from Microsoft shows a sample PresenceRecord response that includes the 'activity' section: `https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/uri/presence/uri-usersmeget` And if I force that exact response into get_presence as follows, it also generates errors for the 'activity' section: ``` json_string = """ { "xuid": "0123456789", "state": "online", "devices": [ { "type": "D", "titles": [ { "id": "12341234", "name": "Contoso 5", "state": "active", "placement": "fill", "timestamp": "2012-09-17T07:15:23.4930000", "activity": { "richPresence": "Team Deathmatch on Nirvana" } }, { "id": "12341235", "name": "Contoso Waypoint", "timestamp": "2012-09-17T07:15:23.4930000", "placement": "snapped", "state": "active", "activity": { "richPresence": "Using radar" } } ] }, { "type": "W8", "titles": [ { "id": "23452345", "name": "Contoso Gamehelp", "state": "active", "placement": "full", "timestamp": "2012-09-17T07:15:23.4930000", "activity": { "richPresence": "Nirvana page" } } ] } ] } """ return PresenceItem.model_validate_json(json_string) ``` The errors: ``` 3 validation errors for PresenceItem devices.0.titles.0.activity Input should be a valid array [type=list_type, input_value={'richPresence': 'Team Deathmatch on Nirvana'}, input_type=dict] For further information visit https://errors.pydantic.dev/2.12/v/list_type devices.0.titles.1.activity Input should be a valid array [type=list_type, input_value={'richPresence': 'Using radar'}, input_type=dict] For further information visit https://errors.pydantic.dev/2.12/v/list_type devices.1.titles.0.activity Input should be a valid array [type=list_type, input_value={'richPresence': 'Nirvana page'}, input_type=dict] For further information visit https://errors.pydantic.dev/2.12/v/list_type ``` And these errors are pydantic not liking something about what should be a valid JSON from Xbox. How to formally solve? @tr4nt0r <br/> <hr/> <details><summary>This repo is using Opire - what does it mean? 👇</summary><br/>💵 Everyone can add rewards for this issue commenting <code>/reward 100</code> (replace <code>100</code> with the amount).<br/>🕵️‍♂️ If someone starts working on this issue to earn the rewards, they can comment <code>/try</code> to let everyone know!<br/>🙌 And when they open the PR, they can comment <code>/claim #85</code> either in the PR description or in a PR's comment.<br/><br/>🪙 Also, everyone can tip any user commenting <code>/tip 20 @tomballgithub</code> (replace <code>20</code> with the amount, and <code>@tomballgithub</code> with the user to tip).<br/><br/>📖 If you want to learn more, check out our <a href="https://docs.opire.dev">documentation</a>.</details>
kerem 2026-02-28 01:19:06 +03:00
Author
Owner

@tomballgithub commented on GitHub (Jan 21, 2026):

The fix is to edit pythonxbox\api\provider\presence\models.py from:
activity: list[ActivityRecord] | None = None
to
activity: ActivityRecord | None = None

The activity record is defined as being a dict rather than a list. The current code is looking for a list.
https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/json/json-titlerecord

<!-- gh-comment-id:3776116806 --> @tomballgithub commented on GitHub (Jan 21, 2026): The fix is to edit `pythonxbox\api\provider\presence\models.py` from: ` activity: list[ActivityRecord] | None = None` to ` activity: ActivityRecord | None = None` The activity record is defined as being a dict rather than a list. The current code is looking for a list. [https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/json/json-titlerecord](https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/json/json-titlerecord)
Author
Owner

@tr4nt0r commented on GitHub (Jan 21, 2026):

Yeah, I forked python-xbox-webapi because it is unmaintained and I also had to fix some outdated models. This fork has now replaced the library in the Home Assistant integration. Please feel free to open a bugfix PR, I will release a new version to pypi as soon as it is merged.

<!-- gh-comment-id:3777148501 --> @tr4nt0r commented on GitHub (Jan 21, 2026): Yeah, I forked `python-xbox-webapi` because it is unmaintained and I also had to fix some outdated models. This fork has now replaced the library in the [Home Assistant integration](https://www.home-assistant.io/integrations/xbox/). Please feel free to open a bugfix PR, I will release a new version to pypi as soon as it is merged.
Author
Owner

@tomballgithub commented on GitHub (Jan 22, 2026):

@tr4nt0r I submitted a PR for this

<!-- gh-comment-id:3782064065 --> @tomballgithub commented on GitHub (Jan 22, 2026): @tr4nt0r I submitted a PR for this
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/python-xbox#3
No description provided.