A JSON file cannot be appended to like a text file; to add data, we read the whole file into a Python list or dict, change that object, and write the whole file back. Opening the file in append mode (‘a’) writes a second JSON value after the first one, and the file is no longer valid JSON.
The sections below append a record to a JSON array, add keys to a JSON object, fix the AttributeError that comes from mixing the two, write the file safely, and use JSON Lines for real appends, all on Python 3.14.
1. Steps for Appending to a JSON File
In Python, appending JSON to a file takes three steps.
- Read the JSON file into a Python dict or list.
- Add the new data to that dict or list.
- Write the updated dict or list back to the original file.
To learn the read and write steps in detail, see how to read a JSON file and how to write JSON to a file in Python.
2. Appending to a JSON Array using Python List
The users.json file has a list of 2 users, and we append a third user to it.
[
{"Name": "Person_1", "Age": 11, "Email": "11@gmail.com"},
{"Name": "Person_2", "Age": 22, "Email": "22@gmail.com"}
]
The json.load() function returns a list for a JSON array, so we use append(). Opening the file with encoding=”utf-8″ keeps non-ASCII names intact on every operating system.
import json
filename = "users.json"
with open(filename, encoding="utf-8") as fp:
list_obj = json.load(fp) # list with 2 dicts
list_obj.append({"Name": "Person_3", "Age": 33, "Email": "33@gmail.com"})
with open(filename, "w", encoding="utf-8") as fp:
json.dump(list_obj, fp, indent=4)
The updated file holds three users.
[
{
"Name": "Person_1",
"Age": 11,
"Email": "11@gmail.com"
},
{
"Name": "Person_2",
"Age": 22,
"Email": "22@gmail.com"
},
{
"Name": "Person_3",
"Age": 33,
"Email": "33@gmail.com"
}
]
3. Appending to a JSON Object using Python Dictionary
When the file holds a single JSON object, json.load() returns a dict. We add a new attribute Role and change the existing attribute Age with update().
{"Name": "Person_1", "Age": 11, "Email": "11@gmail.com"}
with open("user.json", encoding="utf-8") as fp:
dict_obj = json.load(fp) # dict
dict_obj.update({"Age": 12, "Role": "Developer"})
with open("user.json", "w", encoding="utf-8") as fp:
json.dump(dict_obj, fp, indent=4)
{
"Name": "Person_1",
"Age": 12,
"Email": "11@gmail.com",
"Role": "Developer"
}
4. AttributeError: ‘dict’ object has no attribute ‘append’
We get this error when the file holds a JSON object but the code treats it as a list. A JSON object {…} loads as a dict, which has no append() method, and a JSON array […] loads as a list.
AttributeError: 'dict' object has no attribute 'append'
To fix the error, we check the loaded type before changing it.
with open("user.json", encoding="utf-8") as fp:
data = json.load(fp)
if isinstance(data, list):
data.append({"Name": "Person_4"}) # a new element in the array
else:
data.update({"Role": "Lead"}) # a new key in the object
5. Writing the File Safely
Opening a file with ‘w’ empties it before json.dump() writes anything, so a crash during the write leaves an empty or half-written file. Writing to a temporary file first and swapping it in with os.replace() avoids that, and a missing file can start as an empty list.
import os
def append_record(filename, record):
try:
with open(filename, encoding="utf-8") as fp:
records = json.load(fp)
except FileNotFoundError:
records = []
records.append(record)
tmp = filename + ".tmp"
with open(tmp, "w", encoding="utf-8") as fp:
json.dump(records, fp, indent=4)
os.replace(tmp, filename) # replaces the old file in one step
append_record("events.json", {"event": "login"})
6. JSON Lines for Real Appending
Rewriting the whole file gets slow for logs and other files that grow all the time. JSON Lines stores one JSON object per line, so we open the file in append mode and write one line per record.
with open("events.jsonl", "a", encoding="utf-8") as fp:
fp.write(json.dumps({"event": "login"}) + "\n")
fp.write(json.dumps({"event": "logout"}) + "\n")
Each line is valid JSON on its own, and reading the file back takes one json.loads() call per line.
7. Appending JSON Without Mistakes
Nested lists and several writers make appending harder than the single-file examples.
7.1. Can we append to a JSON file without reading it first?
Not to a regular JSON file, because the closing bracket of the array has to move. A JSON Lines file allows it, as shown in the previous section.
7.2. How do we add an element to a list inside a JSON object?
We load the object, append to the inner list and write the object back.
team = {"name": "core", "members": ["Ana"]}
team["members"].append("Lokesh")
text = json.dumps(team) # '{"name": "core", "members": ["Ana", "Lokesh"]}'
7.3. What happens if two programs append to the same file at once?
Both read the old content, and the second write loses the first change. A file lock around the read and the write prevents that, and for many writers a database is the better store.
7.4. Why not open the file with ‘r+’ and seek back?
It works only with f.seek(0) before the write and f.truncate() after it, otherwise old bytes stay at the end when the new JSON is shorter.
8. Conclusion
Appending to a JSON file means reading it, changing the list or dict, and writing it back. We check whether the data loaded as a list or a dict, write through a temporary file with os.replace(), and switch to JSON Lines when records arrive often.
9. References
Happy Learning !!