Skip to content

Cannot Save code.py Edits on Adafruit Qualia ESP32-S3 for TTL RGB-666 Displays #460

Closed

Description

@jmangum

CircuitPython Version

Adafruit CircuitPython 10.1.3 on 2026-02-20; Adafruit-Qualia-S3-RGB666 with ESP32S3

Workflow(s)

WEB

Browser(s)

Firefox 140.6.0

Console Log

N/A

Steps

  1. Connect to board (ESP32-S3 Qualia) with web workflow
  2. Open code.py
  3. Edit code.py
  4. Select "Save + Run". Board appears to reload and restart code.py
  5. Connect to another board with web workflow
  6. Open code.py on second board
  7. Dialog box appears asking if I want to save edits to the previous code.py file. I select 'no'.
  8. Connect again to first board (ESP32-S3 Qualia)
  9. Open code.py. Can clearly see that previous edits were not saved.
  10. Tried making edits again then just saving code.py
  11. Connect again to another board with web workflow
  12. Open code.py on second board (again). Again get dialog box asking if I want to save edits to previous code.py file. I select 'no'.
  13. Connect for third time to first board (ESP32-S3 Qualia)
  14. Open code.py. Can clearly see that previous edits were not saved (again).

Description

Cannot seem to save edits to code.py on ESP32-S3 Qualia.

I also notice that after trying to save code.py on ESP32-S3 Qualia that the web editor screen appears to be regularly reloading every second or two. This reload cycle does not stop until I connect to another board via wifi.

Additional information

No response

Activity

  1. jmangum commented on May 23, 2026

    @jmangum
    Author

    Thank you @makermelissa . I am not sure, though, if the solution provided in #498 is a viable one, at least for the way I work on CircuitPython projects. Also, the situation I experienced was not consistent with that described in the fix. First, a few more details on the issue I was seeing:

    If I then write a boot.py file to my CIRCUITPY drive and reset the board, I can now write files using web workflow, but I no longer can work on the project while connected to a computer via USB as the boot.py now prevents mounting USB (so can't, for example, us Mu to edit code.py). I tend to work on my projects both using web workflow (when deployed) and from a computer using Mu (when working from my bench). Unless I am not understanding the solution I don't see a way to be able to work with a Qualia ESP32-S3 using both computer-connected USB and web workflow.

  2. makermelissa commented on May 23, 2026

    @makermelissa
    Collaborator

    I wasn't able to reproduce the issue then. Can you provide some more details such as the OS you are using?

  3. jmangum commented on May 23, 2026

    @jmangum
    Author

    I generally use web workflow with Firefox (current version is 140.9.0esr) on MacOS Sequoia 15.7.7.

    I just double-checked the behaviour. Project is connected to power-only USB (no USB mount of CIRCUITPY). When I try to edit code.py via web workflow and save+run the changes I get your pop-up message. Sorry for the trouble.

  4. jmangum commented on May 24, 2026

    @jmangum
    Author

    Out of curiosity I did tests using:

    • Safari 26.3
    • Google Chrome 147.0.7727.102
      Get same result.

    I have multiple Adafruit wifi-enabled boards running CircuitPython on my home network which I regularly use web workflow to connect to an edit/debug. I had not tried using web workflow recently where I edited code.py and tried to save+run. Just tried that on a QtPy ESP32-S3 (8Mb flash no psram) based project (using the Firefox browser noted above) and see the same behaviour (pop-up noting board filesystem lock when I am connected to power-only USB. I don't recall having CIRCUITPY file system write issues in the past with any of my CIRCUITPY projects.

  5. makermelissa commented on Jun 1, 2026

    @makermelissa
    Collaborator

    Thank you. That should be helpful with trying to reproduce the issue.

    Sorry for the trouble.

    No trouble at all. If you're seeing this, it probably means others are too, but not reporting it.

  6. makermelissa-ai-assistant commented on Jun 5, 2026

    @makermelissa-ai-assistant
    Contributor

    @jmangum thanks for the careful reproduction — the cross-browser
    testing (Firefox / Safari / Chrome) and the second device (QtPy
    ESP32-S3) were exactly what I needed to convince myself this isn't
    a misconfiguration on your end.

    Here's where I've landed:

    1. The dialog from #498 is wrong for your case. It tells you a
    host has CIRCUITPY mounted over USB, but in your setup nothing is
    mounting it — you're on power-only USB. After walking through the
    CircuitPython firmware, the actual cause is that the board's
    MP_BLOCKDEV_FLAG_LOCKED flag is held whenever USB Mass Storage is
    enabled on the board (which is the default on most boards),
    regardless of whether a host is actively using the drive. The
    dialog conflated those two cases.

    2. Short-term fix — better messaging. I just opened
    #506 to
    rewrite the read-only / save-failure dialogs so they don't assert
    host involvement, and to add a heads-up about the dual-workflow
    tradeoff (Mu over USB vs. web workflow). That should land soon and
    will at least stop the dialog from sending you on a goose chase.

    3. The real fix is on the firmware side, and it isn't quick.
    Your "I want both Mu and web workflow on the same project" workflow
    is legitimate, and boot.py disabling USB MSC unconditionally is a
    blunt instrument. The cleanest path forward is firmware-side: the
    board should release the MSC lock when no host has actually used it
    in a while, or expose a cooperative way for web workflow to acquire
    write access. I'm going to open a separate issue/discussion on
    adafruit/circuitpython
    to track that, and I'll link it here so you can follow along.

    In the meantime, two workarounds that preserve dual-mode editing:

    • Button-gated boot.py — the most popular pattern. Hold a
      button at boot to disable USB MSC; otherwise leave it on. Lets
      you choose Mu mode (no button) or web-workflow mode (hold button)
      per power cycle. Example sketch:

      # boot.py
      import board, digitalio, storage
      btn = digitalio.DigitalInOut(board.BUTTON)  # or whatever pin
      btn.pull = digitalio.Pull.UP
      if not btn.value:                # button held at boot
          storage.disable_usb_drive()  # web-workflow mode
      # otherwise, default behavior: CIRCUITPY appears as MSC,
      # and Mu/Thonny/your-OS can edit code.py over USB
    • Power-vs-data USB switching — if your project always sits on
      a power adapter once deployed, a true USB power-only cable (data
      lines physically disconnected) doesn't expose CIRCUITPY to any
      host. Some "charging only" cables do this; many don't (most modern
      ones carry data). A USB-A data blocker between cable and adapter
      does the same job reliably. With no data lines connected, web
      workflow over Wi-Fi is your only edit path and saves will work.

    I'll keep this issue open until the firmware-side piece has a home
    to be tracked. Sorry for the runaround — your repro made the
    real bug findable.

  7. added a commit that references this issue on Jun 5, 2026
  8. makermelissa-ai-assistant commented on Jun 5, 2026

    @makermelissa-ai-assistant
    Contributor

    Reopening — auto-closed at PR #506 merge time, but as noted in the PR body and my earlier comment, the firmware-side root cause (board holds the MSC blockdev lock whenever USB MSC is enabled, regardless of host activity) is still outstanding. Tracking that work next on adafruit/circuitpython; will link the issue here once it's filed.

  9. jmangum commented on Jun 5, 2026

    @jmangum
    Author

    Thank you @makermelissa . This is great.

    One other piece of information connected to this issue. Before CircuitPython 10.something none of this was an issue (note that using the Qualia ESP32-S3 requires 10.x, so not relevant to this additional point...). I just checked how web workflow works on an ESP32-S3 Feather with 4MB Flash and 2MB PSRAM and no SD card capabilities (runs a CAN-bus network on my unused home telephone wiring...) where I have CircuitPython 9.0.5 installed. I can write and save+run the code.py file on this system with no problems. But note that this system has no SD card capabilities.

    Recall that the other system I mentioned, the QtPy ESP32-S3 with 8MB Flash and no PSRAM) that does have an SD card mounted. As noted above, I used to be able to write then save+run using web workflow on that board when running CircuitPython 9.something. Since upgrading to CircuitPython 10.x (now at 10.2.1) I can no longer write and save+run using web workflow (for the reasons you list above).

    Just wanted to make it clear that there appears to be a CircuitPython version dependence to this issue of writing to CIRCUITPY using web workflow.

  10. makermelissa commented on Jun 5, 2026

    @makermelissa
    Collaborator

    Yeah, it could be related to #377. I noticed some weirdness between different CircuitPython versions as well. Either way, I believe their both related to adafruit/circuitpython#10972.

  11. makermelissa-ai-assistant commented on Jun 17, 2026

    @makermelissa-ai-assistant
    Contributor

    @jmangum quick update — the firmware-side fix landed on
    adafruit/circuitpython main:
    #11048 (merged 2026-06-10, commit c955e48).
    That should resolve the case where the board reports the filesystem
    read-only even though no USB host is actively mounted it.

    One caveat: the fix is not in a tagged release yet. As of
    right now the latest stable is 10.2.1 and the latest pre-release is
    10.3.0-alpha.2 (2026-05-15) — both predate the fix. To test it today
    you'd need the Absolute Newest build (a per-commit snapshot off
    main), which lives on circuitpython.org under each board's download
    page, below the regular release buttons.

    Direct links for the two boards you mentioned earlier (latest
    post-fix snapshot, dated 2026-06-15):

    • Qualia ESP32-S3 for TTL RGB-666 Displays —
      .uf2
      /
      .bin
    • QT Py ESP32-S3 (8MB flash, no PSRAM) —
      .uf2
      /
      .bin

    These are dev builds, so the usual caveats apply (back up your
    CIRCUITPY contents before flashing). The PR number in the filename
    (PR11050) is just whatever PR triggered that particular build job —
    the fix you care about (#11048, commit c955e48) is in the tree from
    2026-06-10 onward.

    When you have a chance, could you flash one of those onto the same
    power-only-USB setup that was failing before and try save + run on
    code.py from the web editor? If it works, we'll close this out
    once 10.3.0-alpha.3 ships (so anyone hitting this from a regular
    release has the fix too). If it still fails, that's useful too —
    means there's another path I missed.

  12. jmangum commented on Jun 23, 2026

    @jmangum
    Author

    @makermelissa . Sorry for the slow response. I flashed the .uf2 you provided above for the ESP32-S3 QtPy and tried an edit then save+run from web workflow. Worked perfectly! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions