TypeError when attempting to install OS update.
I am running into trouble when trying to run 'codexctl install' on my reMarkable RM100.
./codexctl install updates/3.3.2.1666_reMarkable-Ak1sdSSGWD-.signed
Would you like to use a password to connect? (Y/n):
Enter RM SSH password: **********
Success: Connected to device
Failed to get the version number from the filename, please enter it: 3.3.2.1666
Starting fake updater at 10.11.99.6:8085
Checking if device can connect to this machine
Starting update service on device
Updating...
requested: 2.5.0.27
platform: reMarkable
----------------------------------------
Exception occurred during processing of request from ('10.11.99.1', 43672)
Traceback (most recent call last):
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 318, in _handle_request_noblock
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 349, in process_request
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 362, in finish_request
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 672, in __init__
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 766, in __init__
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 436, in handle
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 424, in handle_one_request
File "/tmp/onefile_9755_1763390312_587915/codexctl/server.py", line 112, in do_POST
TypeError: string indices must be integers, not 'str'
----------------------------------------
Updating...
requested: 2.5.0.27
platform: reMarkable
----------------------------------------
Exception occurred during processing of request from ('10.11.99.1', 43674)
Traceback (most recent call last):
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 318, in _handle_request_noblock
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 349, in process_request
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 362, in finish_request
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 672, in __init__
File "/tmp/onefile_9755_1763390312_587915/socketserver.py", line 766, in __init__
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 436, in handle
File "/tmp/onefile_9755_1763390312_587915/http/server.py", line 424, in handle_one_request
File "/tmp/onefile_9755_1763390312_587915/codexctl/server.py", line 112, in do_POST
TypeError: string indices must be integers, not 'str'
----------------------------------------
Updating...
I1117 14:38:55.801147 406 update_engine_client.cc:271] Initiating update check and install.
W1117 14:38:55.818012 406 update_engine_client.cc:64] Error getting dbus proxy for no.remarkable.update1: GError(3): Could not get owner of name 'no.remarkable.update1': no such name
I1117 14:38:55.818154 406 update_engine_client.cc:54] Retrying to get dbus proxy. Try 2/4
I1117 14:39:05.849915 406 update_engine_client.cc:276] Waiting for update to complete.
E1117 14:39:20.964996 406 update_engine_client.cc:207] Update failed.
Traceback (most recent call last):
File "/tmp/onefile_9755_1763390312_587915/main.py", line 13, in <module>
File "/tmp/onefile_9755_1763390312_587915/codexctl/__init__.py", line 523, in main
File "/tmp/onefile_9755_1763390312_587915/codexctl/__init__.py", line 323, in call_func
File "/tmp/onefile_9755_1763390312_587915/codexctl/device.py", line 661, in install_ohma_update
SystemError: There was an error updating :(
The "TypeError' makes me think that it might be my fault. In response to "Failed to get version number from the filename..." I entered the full version number 3.3.2.1666. Could it be that python is interpreting this as a str? Should I be entering version 3.3, or perhaps the version ID instead of version number?
The file ~/.config/codexctl/version-ids.json exists and shows an entry for version 3.3.2.1666.
status:
Current version: 2.5.0.27
Old update engine: True
Beta active: Release
Version id: 20201127104105
Firmware downloaded using: codexctl download 3.3.2.1666 --hardware rm1 --out .
codexctl is the 2025-11-08 binary compiled for Ubuntu.
I acquired this device used, from a thrift store. I used 'journalctl -a' first thing to grab as much of the history of the device as I could. It appears from this output that the previous owner attempted to update to firmware 3.11.2.5, but that this attempt failed. It seems that it was updated, then shut down without rebooting into 3.11.2.5 until finally it was donated to the thrift store months later. When I powered it up it booted into 2.5.0.27. The 3.11 firmware may still be sitting on the fallback partition. Possibly the device was left in an unstable state. I perfromed a factory reset prior to using codexctl.
https://github.com/Jayy001/codexctl/blob/main/codexctl%2Fserver.py#L112
It's not clear to me where available_versions is being populated from. This looks like it just need to be populated properly.
Upon closer look, available_versions is meant to be populated with a dict where the keys are the device names. My guess is that this line here is setting it to a string instead of the proper value: https://github.com/Jayy001/codexctl/blob/0e278513fb2b40dcf04931d488a787ed06a144a7/codexctl/init.py#L234 This probably works on newer OS versions, as they follow a different update path, but breaks for older ones.
Is the dict sourced from ~/.config/codexctl/version-ids.json? ie:
"3.3.2.1666": [
"Ak1sdSSGWD-",
"9f1ed453241901ecbbae9bc62a567b5cea1df10cc69d9be38ebb1e56a88f8d68"
],
No, as the keys for that value is not the device names.
I don't mean to follow a red herring, but the json file has device names, too:
{
"remarkable1": {
"3.20.0.92": [
"remarkable-production-image-3.20.0.92-rm1-public.swu",
"a7558d9ef4b2bcc41d9a9219822a1e7e34bff46851658dcfd9666856401e9728"
],
"3.19.0.82": [
"remarkable-production-image-3.19.0.82-rm1-public.swu",
"210a1ba88135fb1027e9267cb357909380ce00672f646cc3f2005118e31612fd"
],
If you had passed a version number as part of the command line arguments it would be set to that value: https://github.com/Jayy001/codexctl/blob/0e278513fb2b40dcf04931d488a787ed06a144a7/codexctl/init.py#L60 But looking at your log output, you did not, and you instead provided it: https://github.com/Jayy001/codexctl/blob/0e278513fb2b40dcf04931d488a787ed06a144a7/codexctl/init.py#L241-L250 Which means that the following code will run to get the update_file dict: https://github.com/Jayy001/codexctl/blob/0e278513fb2b40dcf04931d488a787ed06a144a7/codexctl/init.py#L281-L290
It looks like this just needs to be updated to properly identify that update_file needs to be set to the dict instead of passed through.
@Jayy001 likely all of the logic here needs to be un-spagettified to make it easier to follow. Clear separate codepaths that can be fully tested instead of codepaths that have large numbers of variables that tweak and change how it works, such that there are many edge case paths that are not tested.
I successfully updated the OS. My confusion seems to have been with the fact that I executed './codexctl install updates/3.3.2.1666_reMarkable-Ak1sdSSGWD-.signed' using a update file which I had previously downloaded to the desktop. When I ran './codexctl install 3.3.2.166' this was the result:
Would you like to use a password to connect? (Y/n): y
Enter RM SSH password: **********
Success: Connected to device
Version 3.3.2.1666 not found. Attempting to download
2025-11-20 11:35:25.629 | ERROR | codexctl.updates:download_version:191 - Download folder ./updates does not exist! Creating it now.
[==================================================]
Downloaded version 3.3.2.1666 to ./updates/3.3.2.1666_reMarkable-Ak1sdSSGWD-.signed
Starting fake updater at 10.11.99.2:8085
Checking if device can connect to this machine
Starting update service on device
Updating...
requested: 2.5.0.27
platform: reMarkable
10.11.99.1 - - [20/Nov/2025 11:40:38] "POST / HTTP/1.1" 200 -
Updating...
Update downloaded, please wait for device to install...
10.11.99.1 - - [20/Nov/2025 11:41:01] "GET /updates/3.3.2.1666_reMarkable-Ak1sdSSGWD-.signed HTTP/1.1" 200 -
Updating...
Update downloaded, please wait for device to install...
Updating...
Update downloaded, please wait for device to install...
Done! Now rebooting the device and disabling update service
Trying to connect to device
Would you like to use a password to connect? (Y/n): y
Enter RM SSH password: 7FMHsUUliX
Success: Connected to device
Update complete and update service disabled. Restart device to enable it
My error seems to have been in assuming that once I had downloaded the update file to my desktop, that file would be copied to the device. This is apparently not the case. The 'install --help' command seems to imply that it would work, and it probably would if I had been running codecxtl on the device rather than the desktop. A little clarity on this would be helpful, other that that I consider the issue closed. Thanks for your help.
Giving a path to the file is something that is supposed to work.