Skip to content

Bug: Incorrect metadata field access in PromptSampler causes "Unknown changes" in evolution history #203

@hyounjunlee

Description

@hyounjunlee

Hi, I was wondering if the "changes" and "parent_metrics" context inside evolution history template are bugs.

Description

There's a bug in openevolve/prompt/sampler.py where the changes and parent_metrics fields are being accessed incorrectly from program dictionaries, causing the evolution history to always show "Unknown changes" instead of the actual changes made.

Root Cause

The issue occurs in the _format_evolution_history method (lines 252 and 267) where the code attempts to access metadata fields directly from the program dictionary:

# ❌ INCORRECT - these fields are in metadata, not at top level
changes = program.get("changes", "Unknown changes")
parent_metrics = program.get("parent_metrics", {})

However, when Program objects are created, these fields are stored in the metadata dictionary:

# From iteration.py and process_parallel.py:
result.child_program = Program(
    # ... other fields ...
    metadata={
        "changes": changes_summary,          # ← stored in metadata
        "parent_metrics": parent.metrics,    # ← stored in metadata
    },
)

When these Program objects are converted to dictionaries via to_dict() (which uses asdict()), the structure becomes:

{
    "id": "...",
    "code": "...",
    "metrics": {...},
    "metadata": {
        "changes": "Added loop optimization",  # ← actual location
        "parent_metrics": {...}               # ← actual location
    }
    # ... other fields
}

Impact

  • Evolution history always shows "Unknown changes" instead of actual modifications
  • Performance comparison logic fails because parent_metrics is empty {}
  • Users cannot see what changes were made in previous attempts
  • This affects the quality of prompts sent to LLMs for evolution

Files Affected

  • openevolve/openevolve/prompt/sampler.py (lines 252, 267)

Evidence of Correct Pattern

The codebase already shows the correct pattern in _extract_unique_features method (lines 501-503):

# ✅ CORRECT pattern already used elsewhere
metadata = program.get("metadata", {})
if "changes" in metadata:
    changes = metadata["changes"]

Related Code Locations

Program creation with metadata:

  • openevolve/openevolve/iteration.py:130-133
  • openevolve/openevolve/process_parallel.py:228-232

Program to dict conversion:

  • openevolve/openevolve/iteration.py:66
  • openevolve/openevolve/process_parallel.py:157

Correct metadata access pattern:

  • openevolve/openevolve/prompt/sampler.py:501-503

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions