keepmenu icon indicating copy to clipboard operation
keepmenu copied to clipboard

TypeError: replace() argument 2 must be str, not None

Open laur89 opened this issue 1 month ago • 6 comments

Running keepmenu prompts rofi window for password, after which program fails with TypeError:

$ keepmenu

# <passwd is prompted & entered via rofi>

Process DmenuRunner-2:
Traceback (most recent call last):
  File "/usr/lib/python3.13/multiprocessing/process.py", line 313, in _bootstrap
    self.run()
    ~~~~~~~~^^
  File "/data/.local/share/pipx/venvs/keepmenu/lib/python3.13/site-packages/keepmenu/keepmenu.py", line 333, in run
    self.dmenu_run(self.server.totp_flag.is_set())
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/.local/share/pipx/venvs/keepmenu/lib/python3.13/site-packages/keepmenu/keepmenu.py", line 400, in dmenu_run
    sel = view_all_entries(list(options), filtered_entries, self.database.dbase)
  File "/data/.local/share/pipx/venvs/keepmenu/lib/python3.13/site-packages/keepmenu/view.py", line 24, in view_all_entries
    i.deref('username'),
    ~~~~~~~^^^^^^^^^^^^
  File "/data/.local/share/pipx/venvs/keepmenu/lib/python3.13/site-packages/pykeepass/entry.py", line 188, in deref
    return self._kp.deref(getattr(self, attribute))
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/.local/share/pipx/venvs/keepmenu/lib/python3.13/site-packages/pykeepass/pykeepass.py", line 910, in deref
    value = value.replace(ref, getattr(ref_entry, wanted_field))
TypeError: replace() argument 2 must be str, not None

<note process hangs, have to ctrl+c out of it>

Config, commented out lines removed:

[dmenu]
dmenu_command = rofi -dmenu -width 30 -password -i

[dmenu_passphrase]

[database]
database_1 = /data/path/to/my/passwords_file.kdbx

[password_chars]

[password_char_presets]

keepmenu installed via pipx, running debian testing, py 3.13.9 python3-pykeepass & python3-pynput packages are installed via apt.

laur89 avatar Nov 24 '25 10:11 laur89

It seems like there might be an entry in your database that is making pykeepass and keepmenu unhappy.

  1. Can you open the database normally in keepassxc?
  2. Are you able to use pdb or another debugger to figure out which entry is causing the fault?
  3. If you're able to find the entry, send me a sanitized database with just that entry. That'll make it easier to figure out the issue.

firecat53 avatar Nov 24 '25 19:11 firecat53

Looks like issue is when entry B item (say username) is pointing to another entry A (i.e. value like {REF:U@I:C5280B2CCDE436AFA96D11390114BB82}), and A's username is left empty.

Reproduction:

  1. open keepassxc GUI
  2. create a new db
  3. create entry A - do not set any fields
  4. create entry B by cloning A and tick Replace username and password with references
  5. run keepmenu

Unrelated, but why does keepmenu stay running and needs to be ctrl-c'd out, even in happy path?

laur89 avatar Nov 25 '25 00:11 laur89

I pushed a fix to the develop branch. Please test and see it fixes the issues for you.

Keepmenu always has a daemon running in the background...that's by design. You would normallly open it initially using a keybinding. Does that answer your question?

Thanks for the report!

firecat53 avatar Nov 25 '25 20:11 firecat53

Fix works, thanks for the quick response.

Keepmenu always has a daemon running

Ah, makes sense. Otherwise the caching couldn't work without super insecure persisted unlocked cache either.

Will leave the issue open 'til its on master.

laur89 avatar Nov 26 '25 10:11 laur89

Re. fix - wouldn't you agree it's an issue with pykeepass' deref() implementation and should be fixed upstream instead? Any idea how open they are for such changes/propositions?

laur89 avatar Nov 26 '25 10:11 laur89

Yeah, it seems like it could be an upstream issue without diving in too deep. I've worked with them in the past on pykeepass issues/testing. I'll leave this open to remind myself to submit an issue with them.

firecat53 avatar Nov 26 '25 15:11 firecat53