{"record":{"id":"9339edd1fc37f61f","repo":"TheAlgorithms/Python","slug":"var-name-must-be-a-dict","errorCode":null,"errorMessage":"{var_name} must be a dict","messagePattern":"(.+?) must be a dict","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"dynamic_programming/viterbi.py","lineNumber":364,"sourceCode":"    Traceback (most recent call last):\n            ...\n    ValueError: mock_name must be a dict\n    >>> _validate_dict({\"a\": 8}, \"mock_name\", dict)\n    Traceback (most recent call last):\n            ...\n    ValueError: mock_name all values must be dict\n    >>> _validate_dict({2: 0.5}, \"mock_name\",float, True)\n    Traceback (most recent call last):\n            ...\n    ValueError: mock_name all keys must be strings\n    >>> _validate_dict({\"b\": 4}, \"mock_name\", float,True)\n    Traceback (most recent call last):\n            ...\n    ValueError: mock_name nested dictionary all values must be float\n    \"\"\"\n    if not isinstance(_object, dict):\n        msg = f\"{var_name} must be a dict\"\n        raise ValueError(msg)\n    if not all(isinstance(x, str) for x in _object):\n        msg = f\"{var_name} all keys must be strings\"\n        raise ValueError(msg)\n    if not all(isinstance(x, value_type) for x in _object.values()):\n        nested_text = \"nested dictionary \" if nested else \"\"\n        msg = f\"{var_name} {nested_text}all values must be {value_type.__name__}\"\n        raise ValueError(msg)\n\n\nif __name__ == \"__main__\":\n    from doctest import testmod\n\n    testmod()\n","sourceCodeStart":346,"sourceCodeEnd":378,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/dynamic_programming/viterbi.py#L346-L378","documentation":"Raised by viterbi's _validate_dict (dynamic_programming/viterbi.py:364) when one of the probability parameters (initial_probabilities, transition_probabilities, emission_probabilities, or their nested rows) is not a Python dict. These parameters are keyed by state/symbol names, so lists, strings, or numbers are rejected with the parameter name interpolated into the message.","triggerScenarios":"Calling viterbi with transition_probabilities=[['a',0.5]] or 'invalid' instead of {'rainy': {'rainy': 0.7, ...}}; passing a numpy 2-D matrix instead of a dict-of-dicts; passing a pandas DataFrame. The doctest shows _validate_dicts('invalid', ...) hitting exactly this path.","commonSituations":"Representing transition matrices as 2-D arrays from numerical code and passing them straight in; JSON configs where a nested object was flattened into a list; assuming the library accepts matrix-style HMM parameters.","solutions":["Convert matrices to dict-of-dicts keyed by state names: {s_i: {s_j: matrix[i][j] for j, s_j in enumerate(states)} for i, s_i in enumerate(states)}.","For pandas DataFrames use df.to_dict(orient='index') after ensuring column/index labels are the state names.","Check each of the three probability parameters is a dict before calling."],"exampleFix":"# before\nviterbi(obs, states, initial_p, [[0.7, 0.3], [0.4, 0.6]], emit_p)  # ValueError\n\n# after\ntrans_p = {'rainy': {'rainy': 0.7, 'sunny': 0.3}, 'sunny': {'rainy': 0.4, 'sunny': 0.6}}\nviterbi(obs, states, initial_p, trans_p, emit_p)","handlingStrategy":"type-guard","validationCode":"def is_prob_dict(x: object) -> bool:\n    return isinstance(x, dict)","typeGuard":"def is_prob_dict(x: object) -> TypeGuard[dict]:\n    return isinstance(x, dict)","tryCatchPattern":null,"preventionTips":["Convert matrices with {states[i]: {states[j]: m[i][j] ...}}.","Use df.to_dict(orient='index') for pandas matrices.","Keep HMM parameters in JSON object form, never arrays."],"tags":["dynamic-programming","hmm","type-validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}