training_man: 27.0.1+2494687 writes a non-zero block trailer, training/mentoring readers fail closed
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 49/100
Research direction
Start with _skip_block_trailer in readers/training.py and the contributing guide’s rule for blocking versus advisory checks. Compare the training and mentoring readers against saves with and without mentoring groups; the issue reports the trailer values and that relaxing the assertion lets all gates pass. Done means both readers handle the reported FM27 build while preserving integrity checks and surfacing the unknown word appropriately.
Written by the indexing model from the issue text.
Description
What went wrong
save.training() and save.mentoring() both fail closed on saves from FM27 build 27.0.1+2494687:
UnsupportedGameError: training blocks whose trailer is not all zero are not supported by this layout
The failure is _skip_block_trailer in readers/training.py: the four bytes after a team block's mentoring groups are no longer all zero on this build.
What I found (own saves + the in-game UI)
- The
training_mansection schema is unchanged (32), so the27.0.0+2486695layout is borrowed as expected, and everything else in the walk still decodes: one block per team of the managed club, weekly records stepping exactly seven days across the whole calendar, mentoring group member selectors resolving to player records. - Only blocks that hold mentoring groups carry the non-zero word:
- blocks without groups (the youth and B sides in my club's section): trailer still
00 00 00 00, followed by the terminator byte as before; - the first-team block with 3 mentoring groups:
05 00 00 00(u32 LE = 5) then the terminator; - save-diff against a single in-game event: after creating a 4th mentoring group in the game and saving, the word became
06 00 00 00, and the new group was stored under group number 5 while groups 1-3 exist (no group number 4 anywhere in the section) - so the word may be a group-allocation counter. That is a guess from two data points; I have not decoded it.
- blocks without groups (the youth and B sides in my club's section): trailer still
- With the all-zero assertion relaxed locally (accepting and recording the word, changing nothing else), the full walk and every gate bound pass, which suggests a reserved word now written by the game rather than a wider layout shift.
What I expected
By the contributing guide's own rule - a blocking check needs an integrity condition, population assumptions belong in advisory checks - the all-zero trailer assertion looks like a population assumption about reserved bytes that 27.0.1 now breaks in normal play. Recording the raw word in a warning instead of raising would keep both readers usable on this build while flagging the unknown content. Careers with no mentoring groups set up should read fine (their blocks keep zero trailers).
Environment
- fmsave version: 0.11.0
- Python: 3.14.7
- OS: macOS
- Game build:
27.0.1+2494687(known_build: false, borrows the FM27 27.0.0 layouts)
fmsave validate SAVE --json output (trimmed to the relevant readers)
"section_schemas": { "training_man": 32 },
"readers": [
{ "reader": "training", "status": "error", "record_count": null, "gates": [], "coverage": {}, "anomalies": {} },
{ "reader": "mentoring", "status": "error", "record_count": null, "gates": [], "coverage": {}, "anomalies": {} }
]
All other readers report ok. Happy to send the save privately if useful, or to run any extra probe on it.
- Dominant language
- Python
- Stars
- 28
- Forks
- 8
- Avg merge
- 42m
- Merged PRs (30d)
- 33
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rhiever/fmsave
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
rhiever/fmsave#77 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 43/100
rhiever/fmsave#75 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 52/100
rhiever/fmsave#68 · 6 comments ·
Maintainers usually reply within 1 day
Similar issues
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gke-labs/kube-agents#5671 ·
Maintainers usually reply within 1 day
-
docs(auth): Method B step 4 should tell users to tick "Use this client for an AI-powered agent"Opendocumentation next-release v0.9.6
Difficulty 1/5 Under an hour Newbie friendliness 88/100
khuisman/mcp-gee-sweet#1446 ·
Maintainers usually reply within 1 day
-
model:sonnet runtime:claude security size:S
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
FootprintAI/Containarium#3671 ·
Maintainers usually reply within 1 day
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidaysPossibly taken @shikhabhadoria claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
vacanza/holidays#4116 · 1 comment ·
Maintainers usually reply within 1 day
-
bug CLI exec
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day