### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current behaviour

I randomly encountered this by loading a wallet created from master with an older version. I could trace it down to bd13dc2f46ea10302a928fcf0f53b7aed77ad260 (#26076), but I don't know descriptor wallets enough to understand what's going on (cc @Sjors @achow101).

### Expected behaviour

`bitcoind` starts, or at least tells me to use a later version if #26076 was a breaking change instead of corrupting `wallet.dat`.

### Steps to reproduce

(master, clean chain): 
`createwallet -regtest ""`
(v25.0rc2):
first `bitcoind -regtest` succeeds
then stop and restart the node: The second `bitcoind -regtest` leads to an InitError:
`Error: Error: Unable to expand wallet descriptor from cache`
now, the wallet cannot be loaded by either version.

### Relevant log output

_No response_

### How did you obtain Bitcoin Core

Compiled from source

### What version of Bitcoin Core are you using?

v25.0rc2 / master

### Operating system and version

Ubuntu

### Machine specifications

_No response_
{
    /** A character set designed such that:
     *  - The most common 'unprotected' descriptor characters (hex, keypaths) are in the first group of 32.
     *  - Case errors cause an offset that's a multiple of 32.
     *  - As many alphabetic characters are in the same group (while following the above restrictions).
     *
     * If p(x) gives the position of a character c in this character set, every group of 3 characters
     * (a,b,c) is encoded as the 4 symbols (p(a) & 31, p(b) & 31, p(c) & 31, (p(a) / 32) + 3 * (p(b) / 32) + 9 * (p(c) / 32).
     * This means that changes that only affect the lower 5 bits of the position, or only the higher 2 bits, will just
     * affect a single symbol.
     *
     * As a result, within-group-of-32 errors count as 1 symbol, as do cross-group errors that don't affect
     * the position within the groups.
     */
    static std::string INPUT_CHARSET =
        "0123456789()[],'/*abcdefgh@:$%{}"
        "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
        "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
    
    static std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
    uint64_t c = 1;
    int cls = 0;
    int clscount = 0;
    for (auto ch : span) {
        auto pos = INPUT_CHARSET.find(ch);
        if (pos == std::string::npos) return "";
        c = PolyMod(c, pos & 31);