{"record":{"id":"afab627c0541a8bf","repo":"donnemartin/interactive-coding-challenges","slug":"string-must-be-of-type-str","errorCode":null,"errorMessage":"string must be of type str","messagePattern":"string must be of type str","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"recursion_dynamic/longest_substr_k_distinct/longest_substr_solution.ipynb","lineNumber":102,"sourceCode":"  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def longest_substr(self, string, k):\\n\",\n    \"        if not isinstance(string, str):\\n\",\n    \"            raise TypeError('string must be of type str')\\n\",\n    \"        if not isinstance(k, int):\\n\",\n    \"            raise TypeError('k must be of type int')\\n\",\n    \"        low_index = 0\\n\",\n    \"        max_length = 0\\n\",\n    \"        chars_to_index_map = {}\\n\",\n    \"        for index, char in enumerate(string):\\n\",\n    \"            chars_to_index_map[char] = index\\n\",\n    \"            if len(chars_to_index_map) > k:\\n\",\n    \"                low_index = min(chars_to_index_map.values())\\n\",\n    \"                del chars_to_index_map[string[low_index]]\\n\",\n    \"                low_index += 1\\n\",\n    \"            max_length = max(max_length, index - low_index + 1)\\n\",\n    \"        return max_length\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/recursion_dynamic/longest_substr_k_distinct/longest_substr_solution.ipynb#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Decode bytes inputs: string.decode('utf-8') or open files in text mode","Coerce with str(value) if stringification is intended","Verify with isinstance(string, str) before the call in dynamic code paths"],"exampleFix":"// before\nlength = sol.longest_substr(raw_bytes, k=2)\n// after\nlength = sol.longest_substr(raw_bytes.decode('utf-8'), k=2)","handlingStrategy":"type-guard","validationCode":"if not isinstance(string, str):\n    string = string.decode('utf-8') if isinstance(string, bytes) else str(string)\nsol.longest_substr(string, k)","typeGuard":"def is_str(x):\n    return isinstance(x, str)","tryCatchPattern":"try:\n    sol.longest_substr(string, k)\nexcept TypeError as e:\n    if 'type str' in str(e):\n        string = str(string)\n        n = sol.longest_substr(string, k)","preventionTips":["Open files in text mode","Decode bytes at system boundaries"],"tags":["python","type-check","string","sliding-window","input-validation"],"backgroundTag":"wrong-argument-type","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}