FoundationAgents/MetaGPT · error · FileNotFoundError

json_file: {jsonl_file} not exist, return []

Error message

json_file: {jsonl_file} not exist, return []

What it means

read_jsonl_file in metagpt/utils/common.py raises FileNotFoundError when the given .jsonl path does not exist. The message text mistakenly says 'json_file' and 'return []' (copied from read_json_file), but the behavior is a raise, so callers cannot rely on the message wording.

Source

Thrown at metagpt/utils/common.py:614

        tip = f"Cannot serialize object of type '{type(x).__name__}'"

    raise TypeError(tip)


def write_json_file(json_file: str, data: Any, encoding: str = "utf-8", indent: int = 4, use_fallback: bool = False):
    folder_path = Path(json_file).parent
    if not folder_path.exists():
        folder_path.mkdir(parents=True, exist_ok=True)

    custom_default = partial(to_jsonable_python, fallback=handle_unknown_serialization if use_fallback else None)

    with open(json_file, "w", encoding=encoding) as fout:
        json.dump(data, fout, ensure_ascii=False, indent=indent, default=custom_default)


def read_jsonl_file(jsonl_file: str, encoding="utf-8") -> list[dict]:
    if not Path(jsonl_file).exists():
        raise FileNotFoundError(f"json_file: {jsonl_file} not exist, return []")
    datas = []
    with open(jsonl_file, "r", encoding=encoding) as fin:
        try:
            for line in fin:
                data = json.loads(line)
                datas.append(data)
        except Exception:
            raise ValueError(f"read jsonl file: {jsonl_file} failed")
    return datas


def add_jsonl_file(jsonl_file: str, data: list[dict], encoding: str = None):
    folder_path = Path(jsonl_file).parent
    if not folder_path.exists():
        folder_path.mkdir(parents=True, exist_ok=True)

    with open(jsonl_file, "a", encoding=encoding) as fout:
        for json_item in data:

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Check Path(jsonl_file).resolve() exists before calling.
  2. Treat a missing file as an empty trajectory: if not p.exists(): rows = [].
  3. Use absolute paths anchored to the project/workspace root.
  4. Ensure the producing process actually created and flushed the file.

Example fix

# before
rows = read_jsonl_file('out/run1.jsonl')  # raises if run never wrote

# after
from pathlib import Path
p = Path('out/run1.jsonl')
rows = read_jsonl_file(str(p)) if p.exists() else []
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def jsonl_readable(jsonl_file: str) -> bool:
    return Path(jsonl_file).is_file()

Try / catch

try:
    rows = read_jsonl_file(path)
except FileNotFoundError:
    rows = []  # first run / empty history is a normal case

Prevention

When it happens

Trigger: read_jsonl_file('workspace/ trajectory.jsonl') before any rows were appended; wrong relative path under a different cwd; typo in the filename; the producer writes only on flush and the file was never created.

Common situations: Reading a trajectory/history file that is created lazily on first write; batch scripts run from a different directory; case-sensitivity or extension mismatch (.json vs .jsonl).

Related errors


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/524f2e13332d411b. Report an issue: GitHub.