Software Development

Why does ast.literal_eval() raise a "ValueError: malformed node or string" and how do I fix it?

TH Asked by Thomas Miller · 11-05-2025
0 upvotes 18,342 views 0 comments
The question

I am trying to use ast.literal_eval() to safely convert strings into Python objects like lists or dictionaries. However, I keep encountering the error ValueError: malformed node or string. I thought this function was a safer alternative to eval(), but it seems to fail on strings that I expect to be valid. What are the common causes for this—such as passing a non-string object, including mathematical operations like 1+2, or using JSON-style values like true, false, or null? Should I be using json.loads() instead, or is there a way to sanitize my strings so that ast.literal_eval() can process them correctly?

3 answers

0
PA
Answered on 08-04-2025

The "malformed node or string" error occurs because ast.literal_eval() is strictly designed to evaluate Python literals only (strings, numbers, tuples, lists, dicts, sets, booleans, and None). If your string contains anything else—like a variable name, a function call (datetime.now()), or a math operation (4 + 5)—it will fail. It is not a general-purpose expression evaluator like eval(). To fix this, ensure your input string strictly follows Python syntax. If you are dealing with data from a web API, you are likely actually looking at JSON, which uses true (lowercase) and null instead of Python's True and None. In that case, switch to json.loads(your_string) for a much smoother experience.

[Image showing the difference between a Python Literal (valid) and a Python Expression (invalid for ast.literal_eval)]

0
ST
Answered on 15-04-2025

I noticed that I get this error even when I pass a string that looks like a valid dictionary. It turns out I was accidentally passing the dictionary object itself instead of its string representation! If you run ast.literal_eval({"a": 1}), it crashes because it expects a str. Always ensure you are wrapping your data in quotes or using str(my_data) if you're testing it. 

RI 18-04-2025

Steven, you're spot on. Another sneaky cause is having null in your string. I often fix this by doing ast.literal_eval(my_str.replace("null", "None")), though as Patricia mentioned, if you're doing that much replacement, json.loads() is usually the "cleaner" Software Development choice.

0
LI
Answered on 11-05-2025

If you absolutely need to evaluate math (like "1+2") safely without using the dangerous eval(), you can't use ast.literal_eval(). You'll need a specialized library like simpleeval or a custom AST walker.

TH 15-05-2025

This is a great distinction, Linda. While ast.literal_eval is excellent for safety, its strictness is its main limitation. For anything dynamic, like a calculator app or complex configuration parsing, we often suggest using the numexpr library or building a custom NodeTransformer to only allow specific arithmetic nodes.

Share your thoughts

Your email address will not be published. Required fields are marked (*)

Professional Counselling Session

Still have questions?
Schedule a free counselling session

Our experts are ready to help you with any questions about courses, admissions, or career paths. Get personalized guidance from industry professionals.

Request a Call Back

Search Online

We Accept

We Accept

Follow Us

"PMI®", "PMBOK®", "PMP®", "CAPM®" and "PMI-ACP®" are registered marks of the Project Management Institute, Inc. | "CSM", "CST" are Registered Trade Marks of The Scrum Alliance, USA. | COBIT® is a trademark of ISACA® registered in the United States and other countries.

Book Free Session