[plugin.video.mlbtv@matrix] 2026.4.9+matrix.1#4768
[plugin.video.mlbtv@matrix] 2026.4.9+matrix.1#4768eracknaphobia wants to merge 1 commit intoxbmc:matrixfrom
Conversation
Kodiai Addon Check
0 error(s), 10 warning(s) found. |
Kodiai Review SummaryWhat ChangedUpdates MLB.TV addon to version 2026.4.9+matrix.1 with Kodi 22 playback fixes, Game Changer/Stream Finder improvements, affiliate team updates, restored Big Inning schedule, and no-spoiler enhancements. Reviewed: core logic Strengths
ObservationsImpact[MAJOR] plugin.video.mlbtv/resources/lib/mlb.py (1491): Null pointer dereference in title.replace() [MAJOR] plugin.video.mlbtv/resources/lib/mlb.py (631-639): Missing error handling for ESPN API response [MEDIUM] plugin.video.mlbtv/resources/lib/globals.py (98): Truncated team ID in affiliate data Suggestions
Verdict🔴 Address before merging -- 3 blocking issue(s) found Review Details
|
| break | ||
|
|
||
| if (n == 0): | ||
| title = title.replace('Condensed Game', 'Game Recap') |
There was a problem hiding this comment.
[MAJOR] Null pointer dereference causes crash when title is None
The variable title is initialized to None at line 1473. If no highlight with displayName == 'Condensed Game' is found in the loop (lines 1476-1488), title remains None. Calling .replace() on None raises AttributeError: 'NoneType' object has no attribute 'replace'.
This crashes when processing games that don't have a 'Condensed Game' highlight.
| title = title.replace('Condensed Game', 'Game Recap') | |
| if (n == 0) and title is not None: | |
| title = title.replace('Condensed Game', 'Game Recap') |
| for content in json_source['page']['buckets'][0]['contents']: | ||
| big_inning_date = content['utc'][0:10] | ||
| big_inning_start = str(easternToLocal(parse(content['utc'][0:19]))) | ||
| for stream in content['streams']: | ||
| big_inning_end = str(easternToLocal(parse(content['utc'][0:19]) + timedelta(seconds=stream['durationInSeconds']))) | ||
| if big_inning_date not in big_inning_schedule: | ||
| big_inning_schedule[big_inning_date] = [] | ||
| big_inning_schedule[big_inning_date].append({'start': big_inning_start, 'end': big_inning_end}) | ||
| break |
There was a problem hiding this comment.
[MAJOR] Missing error handling for ESPN API JSON parsing
The code directly accesses nested dictionary keys without validation:
json_source['page']['buckets'][0]['contents']- no check if keys exist or buckets is non-emptycontent['utc'][0:10]andcontent['utc'][0:19]- no check if 'utc' key existscontent['streams']- no check if key existsstream['durationInSeconds']- no check if key exists
If ESPN changes their API structure or returns an error response, this causes KeyError or IndexError, breaking Big Inning schedule functionality.
| for content in json_source['page']['buckets'][0]['contents']: | |
| big_inning_date = content['utc'][0:10] | |
| big_inning_start = str(easternToLocal(parse(content['utc'][0:19]))) | |
| for stream in content['streams']: | |
| big_inning_end = str(easternToLocal(parse(content['utc'][0:19]) + timedelta(seconds=stream['durationInSeconds']))) | |
| if big_inning_date not in big_inning_schedule: | |
| big_inning_schedule[big_inning_date] = [] | |
| big_inning_schedule[big_inning_date].append({'start': big_inning_start, 'end': big_inning_end}) | |
| break | |
| big_inning_schedule = {} | |
| try: | |
| if 'page' in json_source and 'buckets' in json_source['page'] and len(json_source['page']['buckets']) > 0: | |
| for content in json_source['page']['buckets'][0].get('contents', []): | |
| if 'utc' in content and len(content['utc']) >= 19: | |
| big_inning_date = content['utc'][0:10] | |
| big_inning_start = str(easternToLocal(parse(content['utc'][0:19]))) | |
| for stream in content.get('streams', []): | |
| if 'durationInSeconds' in stream: | |
| big_inning_end = str(easternToLocal(parse(content['utc'][0:19]) + timedelta(seconds=stream['durationInSeconds']))) | |
| if big_inning_date not in big_inning_schedule: | |
| big_inning_schedule[big_inning_date] = [] | |
| big_inning_schedule[big_inning_date].append({'start': big_inning_start, 'end': big_inning_end}) | |
| break | |
| except Exception as e: | |
| xbmc.log('Error parsing Big Inning schedule: ' + str(e)) |
| MLB_TEAM_IDS = '108,109,110,111,112,113,114,115,116,117,118,119,120,121,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,158,159,160' | ||
|
|
||
| AFFILIATE_TEAM_IDS = {"Arizona Diamondbacks": "419,516,2310,5368", "Athletics": "237,400,499,524", "Atlanta Braves": "431,432,478,6325", "Baltimore Orioles": "418,488,548,568", "Boston Red Sox": "414,428,533,546", "Chicago Cubs": "451,521,550,553", "Chicago White Sox": "247,487,494,580", "Cincinnati Reds": "416,450,459,498", "Cleveland Guardians": "402,437,445,481", "Colorado Rockies": "259,342,486,538", "Detroit Tigers": "106,512,570,582", "Houston Astros": "482,573,3712,5434", "Kansas City Royals": "541,565,1350,3705", "Los Angeles Angels": "401,460,559,561", "Los Angeles Dodgers": "238,260,456,526", "Miami Marlins": "479,554,564,4124", "Milwaukee Brewers": "249,556,572,5015", "Minnesota Twins": "492,509,1960,3898", "New York Mets": "453,505,507,552", "New York Yankees": "531,537,587,1956", "Philadelphia Phillies": "427,522,566,1410", "Pittsburgh Pirates": "452,477,484,3390", "San Diego Padres": "103,510,584,4904", "San Francisco Giants": "105,461,476,3410", "Seattle Mariners": "403,515,529,574", "St. Louis Cardinals": "235,279,440,443", "Tampa Bay Rays": "233,234,421,2498", "Texas Rangers": "102,448,540,6324", "Toronto Blue Jays": "422,424,435,463", "Washington Nationals": "426,436,534,547"} | ||
| AFFILIATE_TEAM_IDS = {"Arizona Diamondbacks": "419,516,2310,5368", "Athletics": "237,400,499,524", "Atlanta Braves": "431,432,478,6325", "Baltimore Orioles": "418,493,548,568", "Boston Red Sox": "414,428,533,546", "Chicago Cubs": "451,521,550,553", "Chicago White Sox": "247,487,494,580", "Cincinnati Reds": "416,450,459,498", "Cleveland Guardians": "402,437,445,481", "Colorado Rockies": "259,342,486,538", "Detroit Tigers": "106,512,570,582", "Houston Astros": "482,573,3712,5434", "Kansas City Royals": "541,565,1350,3705", "Los Angeles Angels": "460,526,559,56", "Los Angeles Dodgers": "238,260,456,6482", "Miami Marlins": "479,554,564,4124", "Milwaukee Brewers": "249,556,572,5015", "Minnesota Twins": "492,509,1960,3898", "New York Mets": "453,505,507,552", "New York Yankees": "531,537,587,1956", "Philadelphia Phillies": "427,522,566,1410", "Pittsburgh Pirates": "452,477,484,3390", "San Diego Padres": "103,510,584,4904", "San Francisco Giants": "105,461,476,3410", "Seattle Mariners": "401,403,529,574", "St. Louis Cardinals": "235,279,440,443", "Tampa Bay Rays": "233,234,421,2498", "Texas Rangers": "102,448,540,6324", "Toronto Blue Jays": "422,424,435,463", "Washington Nationals": "426,436,534,547"} |
There was a problem hiding this comment.
[MEDIUM] Truncated team ID in Los Angeles Angels affiliate data
The Los Angeles Angels entry ends with "56" while all other team IDs in the dictionary are 3-4 digits (e.g., Baltimore: "493", LA Dodgers: "6482", Seattle: "401,403").
The previous value was "401,460,559,561" (from the diff), and the new value is "460,526,559,56" - this suggests "561" was intended to be the last value but got truncated to "56".
This could cause incorrect affiliate team matching for Los Angeles Angels minor league teams.
Add-on details:
General
Code location
Watch every out-of-market regular season game in the office or on the go. The #1 LIVE
Streaming Sports Service
Description of changes:
Checklist: