donnemartin/interactive-coding-challenges · error · TypeError

string must be of type str

Error message

string must be of type str

What it means

Raised by Solution.longest_substr when string is not an instance of str. Unlike the None-only guards elsewhere, this checks the full type with isinstance, so None, bytes, int, or any non-str object raises. The algorithm iterates the string with enumerate and uses it as dict keys, requiring a real str.

Source

Thrown at recursion_dynamic/longest_substr_k_distinct/longest_substr_solution.ipynb:102

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Solution(object):\n",
    "\n",
    "    def longest_substr(self, string, k):\n",
    "        if not isinstance(string, str):\n",
    "            raise TypeError('string must be of type str')\n",
    "        if not isinstance(k, int):\n",
    "            raise TypeError('k must be of type int')\n",
    "        low_index = 0\n",
    "        max_length = 0\n",
    "        chars_to_index_map = {}\n",
    "        for index, char in enumerate(string):\n",
    "            chars_to_index_map[char] = index\n",
    "            if len(chars_to_index_map) > k:\n",
    "                low_index = min(chars_to_index_map.values())\n",
    "                del chars_to_index_map[string[low_index]]\n",
    "                low_index += 1\n",
    "            max_length = max(max_length, index - low_index + 1)\n",
    "        return max_length"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Decode bytes inputs: string.decode('utf-8') or open files in text mode
  2. Coerce with str(value) if stringification is intended
  3. Verify with isinstance(string, str) before the call in dynamic code paths

Example fix

// before
length = sol.longest_substr(raw_bytes, k=2)
// after
length = sol.longest_substr(raw_bytes.decode('utf-8'), k=2)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(string, str):
    string = string.decode('utf-8') if isinstance(string, bytes) else str(string)
sol.longest_substr(string, k)

Type guard

def is_str(x):
    return isinstance(x, str)

Try / catch

try:
    sol.longest_substr(string, k)
except TypeError as e:
    if 'type str' in str(e):
        string = str(string)
        n = sol.longest_substr(string, k)

Prevention

When it happens

Trigger: Calling longest_substr(None, 2), longest_substr(b'abc', 2), or longest_substr(12345, 2). Any non-str first argument triggers the raise before k is even validated.

Common situations: Reading input as bytes (file/network) and forgetting to decode; passing a numeric or object value by mistake; mixing Python 2-style str handling into Python 3 code.

Understand the failure class

Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/afab627c0541a8bf. Report an issue: GitHub.