File API: failed write >~1KB seems to lock the data volume for the rest of the session

If pd->file->write() is called with a payload bigger than about 1KB and the write fails, every subsequent file API call that needs to resolve a path (mkdir, listfiles, stat, new open) returns -1 with unknown uC-FS error: 1414 (which is FS_ERR_VOL_NOT_MOUNTED upstream) until the app exits. File handles that were already open before the failure keep working fine, so it looks like the path-resolution / mount-state layer is where the failure lives, not the I/O layer underneath.

Reproduces on hardware, SDK 3.0.6, Rev A. Sim doesn't show it.

Repro:

  1. Don't pre-mkdir any data folder subdir.
  2. open("saves/foo.bin", kFileWrite) returns a non-NULL handle.
  3. write(fp, buf, N) with N > 1024 returns -1.
  4. All path-resolving file API calls now return 1414, including for known-good paths.

The reason this took me a while to find: the error string is "vol not mounted" which sounds like a hardware or system issue, but the actual cause is an unrelated failed write somewhere earlier in the same run. No way to recover in-app. So a perfectly normal save flow that happens to fail once will silently break the entire file API for the rest of the session, with the symptom appearing in code that has nothing to do with the actual bug.

If anyone else lands on this looking up "uC-FS error 1414": maybe try scrolling back through your boot log for the earliest failed pd->file->write() with a payload over a few KB.

A few things I didn't nail down. What's the exact byte threshold (mine was 524288, didn't bisect down)? Does going back to the Launcher and re-entering the app reset the mount state, or do you need a full reboot? And does the Lua side have the same behavior or is this only on the C API?

1 Like

@dave , seems to stack overflow in the kernel / fs driver / mapper. Isn't it? If so, it is very important to explain to us

  1. How to prevent it
  2. How to recover after it

Also could be great to cover that kind of errors in the docs.

Hello Scott! I'm trying to reproduce this and not having much luck. Bummer, because we're seeing a ton of 1414 errors logged to memfault in 3.0.6, so it's something we need to fix asap. Some questions for you!

  • If there's no saves subdir in your data folder then trying to open saves/foo.bin should definitely return NULL. Am I missing something here?

  • Where is the buffer that you're writing? When I open just foo.bin (in the root of the data folder) and write to it from a statically allocated (i.e. declared in the global scope) buffer, it works for me. Or up to the 1 MB that I tested, anyway. If I declare it in the function scope, making it a stack allocation, I can only go up to around 7 KB. Any more than that and the system hangs and reboots after the 10 second watchdog timeout. The stack on the game task is only 8 KB, doesn't take much to overflow it.

Thanks for reporting this, it's a great lead to sorting out what's going wrong. If you've got code demonstrating this--even if it's just compiled code, I should be able to figure out what's going wrong in the debugger--it'd be a great help!

ngpc-pd-Build0220.pdx.zip (81.5 KB)

You know what, I am struggling to reproduce this with a simple check now too! I am a bit out of the same headspace I was in but I’m going to keep trying to find a simple C file I can send over. I’ll keep poking at isolating it, but this PDX here reproduces those failures! I’ll respond again if I find anything new out.

Unfortunately we can only detect a stack overflow if the RTOS happens to switch tasks while the stack pointer is out of bounds. But I did find a compiler warning -Wstack-usage that will warn if it see an obvious overflow so I've added that to the SDK.

@dave oh you asked questions too, apologies!

  1. saves/foo.bin question
    I cannot reproduce the open-returns-non-NULL behavior in a fresh minimal pdx — on a clean device with no saves/ dir, my minimal pdx’s open(saves/foo.bin, kFileWrite) correctly returns NULL with err 0710 ("Not found"). But on the full app, with mkdir("saves") having been called (and returning 0), the open returns non-NULL, the write fails, and the FS gets poisoned. So either mkdir reports 0 without actually persisting the directory, or something else in the boot path is corrupting volume state before the write.
  2. Where is the buffer that you’re writing?
    Heap, malloc() of 524288 bytes during app init. Not stack, not global, not DTCM.

In the file I attached in the previous message, watch the console — the smoking-gun lines appear during the boot-time selftests.

Boot log of the repro (excerpt)

The full log is long. Key lines:

[kEventInit ... selftest parade runs ...]
integration selftest: PASS T5 pre-save flash write succeeded = 0xAA
cart-save: chip0 short-write (-1/524288) ← write returns -1
integration selftest: FAIL T5 load_save returned true
integration selftest: done — 28 pass, 2 fail
=== SELFTESTS END ===
rom_picker: listfiles('roms') returned -1 (err='unknown uC-FS error: 1414') — directory may be missing
rom_picker: open-probe MISS: roms/Faselei! ... (err=unknown uC-FS error: 1414)
[every subsequent path-resolving file API call: err 1414]

The chain is:

  1. pd->file->mkdir("saves") is called from kEventInit, returns 0 (reports success).
  2. Selftests run.
  3. Inside the integration selftest's T5 case: pd->file->open("saves/selftest_cart.sav", kFileWrite) returns a non-NULL handle.
  4. pd->file->write(fp, header, 32) returns 32 (success).
  5. pd->file->write(fp, body, 524288) returns -1.
  6. From this point forward, every listfiles / open / mkdir / stat on any subdirectory returns -1 with pd->file->geterr() == "unknown uC-FS error: 1414" .

What I couldn't do —

I tried hard to reduce this to a single-file ~200-line C app. Eight attempts; none triggered the bug, despite matching:

- mkdir of saves/ and roms/ in kEventInit

  • stat() after mkdir
  • Failed kFileRead opens of nonexistent files (matching settings.bin / BIOS attempts)
  • pd->sound->addSource() registration
  • Heap churn (mixed malloc/free pattern, ~2 MB total)
  • A 524288-byte malloc + free + realloc to mimic the production app's allocation pattern
  • Two-step write (32 bytes then 524288 bytes on the same handle)
  • Open + write inside kEventInit
  • 4 MB of static BSS to match the production app's memory footprint
  • A controlled DTCM write at 0x20004020 matching the production app's ITCM relocation

None of those, alone or combined, triggered 1414. Maybe this might be useful when you're hunting Memfault traces — it suggests the failure isn't reachable from a fresh boot via a simple file-API sequence. Something has to "warm up" the state first.

I hate pointing out bugs without having more concrete evidence, let me know if you can think of anything I can do to assist troubleshooting on my end!

No luck here. On first run console showed it running selftest then it said that I needed a ngp file. I put on the first one I could find (SNK vs Capcom), still no error. :frowning: Does it happen for you immediately, or after you've selected a game?

Oh oops, didn't see your reply before posting that. Let me go back and read that!

Interesting! Do you see errors in the console output rom_picker lines after the SELFTESTS END line? Or are those not showing up at all?

EDIT: HA! just saw your edit. Ok!

after SELFTESTS END I have

rom_picker: saw '._README.md'
rom_picker: saw '._SNK Vs Capcom - Match Of The Millennium (JUE) [!].ngp'
rom_picker: saw 'README.md'
rom_picker: saw 'SNK Vs Capcom - Match Of The Millennium (JUE) [!].ngp'
rom_picker: scanned 'roms/' — found 2 ROM(s)
  [0] roms/._SNK Vs Capcom - Match Of The Millennium (JUE) [!].ngp
  [1] roms/SNK Vs Capcom - Match Of The Millennium (JUE) [!].ngp
integration: 2 ROMs found — showing startup picker

(the ._ file is garbage that macos puts on there..)

and nope, I'm not seeing the T5 errors

integration selftest: done — 30 pass, 0 fail

What in tarnation. Here’s what I’m getting with that same file I sent to you:

integration selftest: PASS  T4 0x6F95 = 0x10 (color mirror) = 0x10

integration selftest: PASS  T5 pre-save flash write succeeded = 0xAA

cart-save: chip0 short-write (-1/524288)

integration selftest: PASS  T5 post-overwrite (chip0 dirty) = 0x0

cart-save: no save file at saves/selftest_cart.sav

integration selftest: FAIL  T5 load_save returned true

integration selftest: FAIL  T5 byte restored from save file = 0x0 (expected 0xAA)

integration selftest: done — 28 pass, 2 fail

====================================================

=== SELFTESTS END                                ===

====================================================

rom_picker: listfiles(‘roms’) returned -1 (err=‘unknown uC-FS error: 1414’) — directory may be missing

rom_picker: open-probe MISS:    roms/faselei.ngc (err=unknown uC-FS error: 1414)

rom_picker: open-probe MISS:    roms/cardfighters.ngc (err=unknown uC-FS error: 1414)

rom_picker: open-probe MISS:    roms/Faselei! (USA, Europe).ngc (err=unknown uC-FS error: 1414)

rom_picker: open-probe MISS:    roms/SNK vs. Capcom - Card Fighters’ Clash - Capcom Version (USA, Europe).ngc (err=unknown uC-FS error: 1414)

rom_picker: scanned ‘roms/‘ — found 0 ROM(s)

integration: no ROMs found in roms/. Place a .ngp/.ngpc/.ngc file in /Data/com.solmare.ngpcpd/roms/ via sideload, or in this repo’s Source/roms/ before make.

I’m going to do some digging. You don’t need to add any ROMs to any folder–I’m using an empty pdx.

If you have a chance, could you run a disk checker on the data disk? Disk First Aid on Mac, fsck on Linux, no idea what the equivalent is on Windows. When we get weird stuff like this we'll shrug and say "disk corruption?" but we've never been able to pin it down. It'd be good to at least rule that out here.

I can definitely do that when I’m done with my work day, but just to confirm, are you running this PDX on hardware? Because the errors do not show up in the Simulator.

yes, on a rev 2 unit. I see the 1414 errors on rev 1 units as well in memfault, so I don't think that's the difference.

and no rush! Thank you so much for your time :pray:

oh boy woah hold up hold up hold up one sec

I ran macOS Disk Utility "First Aid" on my Playdate's storage and it found FAT corruption across 19 game directories: every .. entry had an incorrect start cluster, and the FSInfo block's free-cluster count was off by ~124K clusters. So the 1414 may not be a write bug? — it's the firmware correctly refusing to operate on a corrupted filesystem. The question is what's corrupting the .. entries in the first place. The corruption pattern is too uniform to be random: 19 directories all hit, and they span multiple sources (sideloaded /Games/User/*, purchased catalog, season games). Something is consistently mis-writing .. entries. I wasn’t seeing this in 3.0.5 I don’t think? I need to dig some more.

1 Like

I just did a full factory reset, updated the firmware again and had all the games download from Catalog and from the Sideloaded games on my account on play.date. Hmm…

Here was the full output of the first aid, but the 1414 error still shows on my hardware, so this wasn’t as interesting as I was initially thinking!

Running First Aid on          

  “PLAYDATE” (disk5s1)                                                                                                                        

                                                                                                                                              

  Checking file system and repairing if necessary and if possible.                                                                            

  Volume was successfully unmounted.                                                                                                          

  Performing fsck_msdos -y /dev/rdisk5s1                                                                                                      

  ** /dev/rdisk5s1                                                                                                                            

                                                                                                                                              

  ** Phase 1 - Preparing FAT                                                                                                                  

                                                                                                                                              

  ** Phase 2 - Checking Directories                                                                                                           

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.uk.co.tim-martin.ycgb.pdx has incorrect start cluster                                         

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.com.oscarbernardini.focus.pdx has incorrect start cluster                                     

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.com.hydrasoftworks.pocketplanner.pdx has incorrect start cluster                              

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.com.humbletune.ljudbilden.pdx has incorrect start cluster                                     

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.com.hteumeuleu.celeste.pdx has incorrect start cluster                                        

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/User/user.84038.app.crankboyhq.crankboy.pdx has incorrect start cluster                                       

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Purchased/guntrails.pdx has incorrect start cluster                                                           

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Purchased/Ribbit Rogue-v1.0.16.pdx has incorrect start cluster                                                

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Purchased/MDMA.PDX has incorrect start cluster                                                                

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Purchased/TheShapeThatWaits.pdx has incorrect start cluster                                                   

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-001/Crankin.pdx has incorrect start cluster                                                    

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-001/Beats_Beeps_Boogie.pdx has incorrect start cluster                                         

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-001/Whitewater Wipeout.pdx has incorrect start cluster                                         

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-001/Casual Birder.pdx has incorrect start cluster                                              

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-002/The Whiteout.pdx has incorrect start cluster                                               

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-002/wheelsprung_device_1_1_1.pdx has incorrect start cluster                                   

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-002/CircleShot.pdx has incorrect start cluster                                                 

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-002/DigDigDino-ReleaseCandidate-20250423.pdx has incorrect start cluster                       

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  Warning: `..' entry in /Games/Seasons/Season-002/BLIPPO.PDX has incorrect start cluster                                                     

                                                                                                                                              

  Correct? yes                                                                                                                                

                                                                                                                                              

  ** Phase 3 - Checking for Orphan Clusters                                                                                                   

                                                                                                                                              

  Warning: Free space in FSInfo block (892927) not correct (768854)                                                                           

                                                                                                                                              

  Fix? yes                                                                                                                                    

                                                                                                                                              

  Warning: 8521 files, 3075416 KiB free (768854 clusters)                                                                                     

                                                                                                                                              

  Warning:                                                                                                                                    

                                                                                                                                              

  ***** FILE SYSTEM WAS MODIFIED *****                                                                                                        

                                                                                                                                              

  File system check exit code is 0.                                                                                                           

  Restoring the original state found as mounted.                                                                                              

                                                                                                                                              

  Operation successful. 

Interesting! I have a couple of those too. Probably not related but I'll file it and keep an eye on it. If you're still getting the write error after that then I think we can rule out filesystem corruption. I've only got a few games on this one right now so I'll try installing more, see if that makes any difference. :person_shrugging:

Say, did you ever check pd->file->geterr() right after the write() failure?

Oh also, after installing more games I ran First Aid again and all of the pdxes had the wrong .. link. So I suspect it's been that way for a long time and we've never noticed because it's not causing any problems. But I'll go back and check previous versions to be sure

2 Likes