Failed result serialization destroys a previously saved JSON result
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start in src/evaluate/saving.py at the save function, where line 43 runs json.dump(data, f) after the destination is already open for writing. Run the reproducer in the issue to confirm the truncated file, then move serialization to a json.dumps call before the file is opened so a TypeError leaves existing bytes untouched and creates no new file. Done means the reproducer prints Previous result preserved: True, a fresh destination stays absent after failure, and existing saving tests still pass on both dependency stacks; note the reporter indicates a fix and test cases already exist, so check for in-flight work first.
Written by the indexing model from the issue text.
Description
evaluate.save() opens an existing result in write mode before it knows whether the new payload can be JSON-serialized. A serialization error can therefore destroy an earlier valid result and leave an incomplete JSON file.
Reproducer (no Hub downloads):
from pathlib import Path
from tempfile import TemporaryDirectory
import traceback
import numpy as np
import evaluate
with TemporaryDirectory() as directory:
destination = Path(directory) / "results.json"
evaluate.save(destination, accuracy=0.75)
previous = destination.read_bytes()
try:
evaluate.save(destination, accuracy=1.0, details={"scores": np.array([1, 2])})
except TypeError:
traceback.print_exc()
print("Previous result preserved:", destination.read_bytes() == previous)
print(destination.read_text(encoding="utf-8"))
Actual output after the exception:
Previous result preserved: False
{"accuracy": 1.0, "details": {"scores":
Expected: still raise TypeError for unsupported JSON values, but preserve the previous file unchanged. For a new destination, a failed serialization should not leave a partial result file. This is not a request to add NumPy encoding support or promise atomic writes against operating-system/process failures.
Full traceback from the standalone reproduction (installation prefixes shortened):
Traceback (most recent call last):
File "repro.py", line 51, in save_failure
evaluate.save(destination, accuracy=1.0, details={"scores": np.array([1, 2])})
File "src/evaluate/saving.py", line 43, in save
json.dump(data, f)
File "python3.11/json/__init__.py", line 179, in dump
for chunk in iterable:
File "python3.11/json/encoder.py", line 432, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "python3.11/json/encoder.py", line 406, in _iterencode_dict
yield from chunks
File "python3.11/json/encoder.py", line 406, in _iterencode_dict
yield from chunks
File "python3.11/json/encoder.py", line 439, in _iterencode
o = _default(o)
^^^^^^^^^^^
File "python3.11/json/encoder.py", line 180, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type ndarray is not JSON serializable
Reproduced on unchanged main a5db2ad54aaeadf15c7aa1f056bc6f7bbeeb7e5f, macOS 26.6.2 / Darwin 25.6.0, Python 3.11.13, with datasets 2.21.0 / NumPy 1.26.4 and datasets 5.0.1 / NumPy 2.4.6. PyTorch 2.8.0 is installed but is not involved; TensorFlow is not installed.
Searches of open/closed reports for save, overwrite, corruption, serializable, atomic, truncate, and _setup_path found no matching fix. Related #808 handles missing Git and #809 handles dotted directories. The original #7 discusses format choices and JSONL concurrency, not this single-call serialization failure.
A focused fix serializes the payload before opening the destination. Four failure cases cover existing/new files and scalar/nested NumPy values; another case keeps intentional replacement of a valid explicit destination working. These and the existing saving tests pass on both dependency stacks (8 per stack), and repository quality checks pass. All four preservation cases fail on unchanged main.
- Dominant language
- Python
- Stars
- 2.5k
- Forks
- 380
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from huggingface/evaluate
-
radar_plot fails on pandas 3 (data.loc with 1-tuple key)Possibly taken @davrens101 claimed this 4 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
huggingface/evaluate#854 · 1 comment ·
-
exact_match: ignore_punctuation only removes ASCII punctuationPossibly taken @reginaldalfret claimed this 24 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
huggingface/evaluate#836 ·
-
EvaluationSuite.run fails with default args_for_task and mutates supplied kwargsPossibly taken @ktz03 claimed this 36 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
huggingface/evaluate#825 ·
-
exact_match scores two different answers as a perfect match when normalization erases both to the same residuePossibly taken @MahendraMula claimed this 53 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
huggingface/evaluate#822 ·
-
Perplexity metric fails with GPT-2 tokenizerPossibly taken @zanvari claimed this 150 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
huggingface/evaluate#766 · 1 comment ·
All issues in huggingface/evaluate
Similar issues
-
agents nolte-linux security skills
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
nolte/claude-shared#732 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 2 days
-
[Bug] Source archive filter: dry run excludes SystemVerilog (.sv) files with no preflight warningOpen
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
FinanceFlash/unvibecode#906 ·
Maintainers usually reply within 1 day