pymysql.err.OperationalError: (1054, "Unknown column 'salt' in 'field list'") during "bench migrate"

I just got an error
pymysql.err.OperationalError: (1054, “Unknown column ‘salt’ in ‘field list’”)
during “bench migrate”.

$ bench --version

$ bench version
erpnext 14.36.0
frappe 14.47.0
gaskosten 0.0.1 (only boilerplate)
insights 1.0.1

How can I find out when said field was introduced or dropped?
In other words: how can I debug such a state of an installation?

How do I finish incomplete migrations?
Or did I run faster than my feet and need to revert a migration?
How to solve this?

Ok, let’s see. I know about patches:

~/ERPnext/frappe-bench$ cat patches.txt
bench.patches.v4.install_yarn #2

But where do they live?

└─$ find . -name “fix_user_permissions”

└─$ locate fix_user_permissions*

└─$ locate fix_user_permissions

In a pristine current archive (might be useful to find the field name), in local python installation (what actually ran), and compiled in some cache (result of starting migration).

So apparently I didn’t activate the environment at some point in time.
Is this bad? A reason for such errors? Or not important?
Can I catch this up?

After these aside-y questions, let’s go on investigating the error.

└─$ cd /usr/local/lib/python3.11/dist-packages/bench/patches/v5/
└─$ ls -l
total 20
-rw-r–r-- 1 root root 425 Aug 29 20:21
-rw-r–r-- 1 root root 1806 Aug 29 20:21
-rw-r–r-- 1 root root 0 Aug 29 20:21
drwxr-xr-x 2 root root 4096 Aug 29 20:21 pycache
-rw-r–r-- 1 root root 135 Aug 29 20:21
-rw-r–r-- 1 root root 1342 Aug 29 20:21 looks like a candidate for a missing “salt” field, as “salt” most of the time relates to securing passwords.
Ah, and the installation currently doesn’t allow login. “verifying …” endlessly.

└─$ grep salt

└─$ grep salt *.py


Now what? Where are older patches?

└─$ cd … (here are two dots only, not three as in the rendering of the discuss software)

└─$ ls patches.txt pycache v5

Not here.
Well? Any ideas, anyone?

~/ERPnext/frappe-bench/sites$ cat apps.json 
    "frappe": {
        "resolution": {
            "commit_hash": null,
            "branch": null
        "required": [],
        "idx": 1,
        "version": "15.0.0-dev"
    "insights": {
        "is_repo": true,
        "resolution": {
            "commit_hash": "dcba8f651e3dc4a794f750a3519afe4965c3cf67",
            "branch": "develop"
        "required": [],
        "idx": 2,
        "version": "0.6.2"
    "erpnext": {
        "is_repo": true,
        "resolution": {
            "commit_hash": "138133e11df43ec1abda3b56344553ba26cf28ae",
            "branch": "version-14"
        "required": [],
        "idx": 3,
        "version": "14.27.5"
    "gaskosten": {
        "is_repo": true,
        "resolution": {
            "commit_hash": "275f1276a4b7c9ff4aee04b249e94f711b337333",
            "branch": "develop"
        "required": [],
        "idx": 4,
        "version": "0.0.1"

Here there is a mismatch with the version bench version reported:
└─$ bench version
erpnext 14.36.0
frappe 14.47.0
gaskosten 0.0.1
insights 1.0.1

So there seems to be a relict from a formerly installed frappe version from the 15.0.0-dev branch.
It seems the installation has been downversioned at some point.
But why was the version in apps.json not updated to the 14.47.0 version? Is this a bug? Or a feature permitting such kind of “forensic” exercise?

This might have to do with the missing salt field.
So maybe I should investigate :wink: the migration patches of the 15.0.0-dev version to see if there is a clue.

But then, can this be solved, and how? Gracefully, that is. (Scrapping is too easy if you want to really understand.)

Why is there no commit hash for the frappe info in apps.json?

Also, the other versions don’t match.
So the apps.json is old-ish. Why is that?
What’s the workflow which produces this?
And why would down-versioning not update this file?

Where is it used, and for what, anyway?

Other people had the same error and suggested solutions, for instance:

There are some insights to be found there (like in similar threads), but the solution wasn’t enough in my case: another missing field (device) was raised in an error.
So I decided to scrap some non-functioning instances and enjoyed practicing

bench drop-site

and observe it’s functioning, speed, hard disk strain, results, etc.