TheAlgorithms/Python · error · TypeError

ciphertext must be a string

Error message

ciphertext must be a string

What it means

Raised by autokey decrypt() when the ciphertext argument is not a str. decrypt() mirrors encrypt()'s validation: it walks the ciphertext character-by-character with ord() range checks (97-122) and appends recovered characters to the key stream, so it demands a string.

Source

Thrown at ciphers/autokey.py:104

    >>> decrypt("vvjfpk wj ohvp su ddylsv", "")
    Traceback (most recent call last):
        ...
    ValueError: key is empty
    >>> decrypt(527.26, "TheAlgorithms")
    Traceback (most recent call last):
        ...
    TypeError: ciphertext must be a string
    >>> decrypt("", "TheAlgorithms")
    Traceback (most recent call last):
        ...
    ValueError: ciphertext is empty
    >>> decrypt("vvjfpk wj ohvp su ddylsv", 2)
    Traceback (most recent call last):
        ...
    TypeError: key must be a string
    """
    if not isinstance(ciphertext, str):
        raise TypeError("ciphertext must be a string")
    if not isinstance(key, str):
        raise TypeError("key must be a string")

    if not ciphertext:
        raise ValueError("ciphertext is empty")
    if not key:
        raise ValueError("key is empty")

    key = key.lower()
    ciphertext_iterator = 0
    key_iterator = 0
    plaintext = ""
    while ciphertext_iterator < len(ciphertext):
        if (
            ord(ciphertext[ciphertext_iterator]) < 97
            or ord(ciphertext[ciphertext_iterator]) > 122
        ):
            plaintext += ciphertext[ciphertext_iterator]

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass the exact str that encrypt() returned: decrypt(encrypt(p, k), k).
  2. Decode bytes: ciphertext.decode('utf-8') before decrypting.
  3. Verify argument order: decrypt(ciphertext, key).

Example fix

# before
decrypt(b'vvjfpk wj ohvp su ddylsv', 'TheAlgorithms')  # bytes -> TypeError

# after
decrypt('vvjfpk wj ohvp su ddylsv', 'TheAlgorithms')
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(ciphertext, bytes):
    ciphertext = ciphertext.decode('utf-8')
assert isinstance(ciphertext, str)

Type guard

def is_str(v: object) -> bool:
    return isinstance(v, str)

Try / catch

try:
    decrypt(c, k)
except TypeError:
    c = c.decode() if isinstance(c, bytes) else str(c)
    plaintext = decrypt(c, k)

Prevention

When it happens

Trigger: Calling decrypt(527.26, 'TheAlgorithms'), decrypt(None, key), decrypt(b'...', key) (bytes are not str), or any non-str first argument.

Common situations: Round-tripping data that was serialized to bytes after encryption, or passing an int because encrypt() was called with swapped arguments earlier.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/da89c5a5ec9c9d6c. Report an issue: GitHub.