donnemartin/interactive-coding-challenges · error · TypeError

str input cannot be None

Error message

str input cannot be None

What it means

Raised by StringCompare.longest_common_substr when str0 or str1 is None. The DP table is sized from len(str0)+1 and len(str1)+1 immediately after the guard, so None is rejected with a descriptive TypeError rather than the implicit 'NoneType has no len()' error.

Source

Thrown at recursion_dynamic/longest_substring/longest_common_substr_solution.ipynb:126

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class StringCompare(object):\n",
    "\n",
    "    def longest_common_substr(self, str0, str1):\n",
    "        if str0 is None or str1 is None:\n",
    "            raise TypeError('str input cannot be None')\n",
    "        # Add one to number of rows and cols for the dp table's\n",
    "        # first row of 0's and first col of 0's\n",
    "        num_rows = len(str0) + 1\n",
    "        num_cols = len(str1) + 1\n",
    "        T = [[None] * num_cols for _ in range(num_rows)]\n",
    "        for i in range(num_rows):\n",
    "            for j in range(num_cols):\n",
    "                if i == 0 or j == 0:\n",
    "                    T[i][j] = 0\n",
    "                elif str0[j-1] != str1[i-1]:\n",
    "                    T[i][j] = max(T[i][j-1],\n",
    "                                  T[i-1][j])\n",
    "                else:\n",
    "                    T[i][j] = T[i-1][j-1] + 1\n",
    "        results = ''\n",
    "        i = num_rows - 1\n",
    "        j = num_cols - 1\n",
    "        # Walk backwards to determine the substring\n",

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Normalize inputs: (str0 or '') and (str1 or '') before calling
  2. Add isinstance(x, str) validation at your API boundary
  3. Ensure upstream loaders substitute '' for missing text

Example fix

// before
n = sc.longest_common_substr(row_a.text, row_b.text)
// after
n = sc.longest_common_substring = sc.longest_common_substr(row_a.text or '', row_b.text or '')
Defensive patterns

Strategy: type-guard

Validate before calling

str0 = str0 or ''
str1 = str1 or ''
sc.longest_common_substr(str0, str1)

Type guard

def is_str_pair(a, b):
    return isinstance(a, str) and isinstance(b, str)

Try / catch

try:
    sc.longest_common_substr(a, b)
except TypeError:
    result = 0

Prevention

When it happens

Trigger: Calling longest_common_substr(None, s) or longest_common_substr(s, None). Empty strings are valid inputs and yield a result of 0; only None raises.

Common situations: Comparing nullable database text columns; one side of the comparison coming from a failed fetch; optional parameters that were never supplied.

Related errors


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