Skip to content

fix(saving): tolerate unknown dependency keys during load - #91

Open
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-saving-tolerate-unknown-dependency-keys-during-d46f74
Open

fix(saving): tolerate unknown dependency keys during load#91
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-saving-tolerate-unknown-dependency-keys-during-d46f74

Conversation

@detail-app

@detail-app detail-app Bot commented Sep 6, 2026

Copy link
Copy Markdown

Warning

GitHub issue creation failed

Detail attempted to publish this bug to GitHub, but the issue could not be created. This fix PR was created without that issue, and missing tracker references are shown as Unknown issue.

You can review and merge this PR normally. Please review your tracker integration settings before the next publish run.

Detail bug report: View on Detail

Summary

Closes Unknown issue

The version-check loop in both loaders (dspy.utils.saving.load and BaseModule.load) iterated the saved dependency-version keys and indexed the current environment's dict with an unguarded dependency_versions[key]. A saved metadata entry the loading environment doesn't track — e.g. a future DSPy that adds a key to get_dependency_versions() — raised an unhandled KeyError, aborting the entire load before any state was read. This contradicts the documented "version mismatches warn, don't block" / "old saves load against newer DSPy versions" contract, and bit hardest on the safe, pickle-free JSON state path (module.load("x.json"), no allow_pickle needed).

Fix

Replaced the unguarded dependency_versions[key] lookup with dependency_versions.get(key) in both loaders. When a saved key is absent from the current environment, the loader now logs a warning naming the dependency and continues; the load proceeds. Known-key mismatch handling and the allow_pickle gates are unchanged. The same one-line-pattern fix applies to both the full-program path (dspy/utils/saving.py) and the state-only .json/.pkl path (dspy/primitives/base_module.py).

Testing

  • New regression tests (one per loader path) asserting an unknown saved key logs a "not tracked" warning and the load still succeeds with matching state:
    • tests/utils/test_saving.py::test_load_with_unknown_dependency_key (full-program path)
    • tests/primitives/test_base_module.py::test_json_load_with_unknown_dependency_key (JSON state path, no allow_pickle)
  • Existing save/load regression tests still pass: test_load_with_version_mismatch (both files), test_json_file_loading_works_without_permission, the pickle-permission tests, and the same-version round-trips (test_save_and_load_with_json, test_save_and_load_with_pkl). Full sweep of tests/utils/test_saving.py and tests/primitives/test_base_module.py with --extra: 24 passed, 3 skipped (the skipped tests need a live LM).
  • Non-versioned verification: also confirmed, via a temporary check, that an unknown key combined with mismatched known keys fires both warning types and still loads — guarding the continue-vs-break interaction — but kept the committed test set minimal for this simple bug.
  • End-to-end reproducer: saving a dspy.Predict to .json, injecting an extra numpy key into the embedded metadata, and loading without allow_pickle previously crashed with KeyError -> 'numpy'; it now logs the untracked-key warning and loads with matching state. The identical scenario on the full-program path (dspy.load(path, allow_pickle=True) with an extra key in metadata.json) also now succeeds.
  • Live-LM tests: the two @pytest.mark.llm_call usage-tracker tests were run against a local Ollama server (ollama/llama3.2:3b) and pass; they exercise usage tracking, not this fix.
  • Not verified: test_usage_tracker_in_parallel hardcodes openai/gpt-4o-mini/gpt-3.5-turbo and is gated on OPENAI_API_KEY; a dummy key was attempted and the test ran but failed with an OpenAI authentication error. No valid OpenAI key was available. This test is unrelated to saving/loading.
  • Lint/format: ruff check and ruff format --check show no new violations on the changed lines; the three remaining findings are pre-existing in unrelated tests and present in the upstream parent commit.

AI-Generated Contributions

Authored by Detail: Automatic Fixes. The fix and tests were generated from the bug report and verified against the included reproduction; no separate prompts were used beyond the report itself.


Automatic Fixes PRs can be configured here.

@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes both DSPy persistence loaders tolerate dependency keys that are absent from the current version registry.

  • Unknown saved dependency keys now produce a warning instead of raising KeyError.
  • Known dependency-version mismatches retain their existing warning behavior.
  • Regression tests verify successful full-program and JSON state loading with unknown dependency metadata.

Confidence Score: 5/5

The PR appears safe to merge; both loader paths handle unknown dependency keys without weakening pickle trust gates or known-version mismatch checks.

No actionable failures remain: the missing-key handling matches the dependency-version provider’s string-valued contract, and the tests exercise the real metadata persistence and loading paths.

Important Files Changed

Filename Overview
dspy/primitives/base_module.py State loading now warns and continues when saved metadata contains an untracked dependency key.
dspy/utils/saving.py Full-program loading now handles unknown saved dependency keys without aborting deserialization.
tests/primitives/test_base_module.py Adds a JSON state-loading regression test covering unknown dependency metadata and restored state.
tests/utils/test_saving.py Adds a full-program loading regression test confirming an unknown dependency key warns without blocking loading.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Read saved dependency metadata] --> B{Key tracked currently?}
    B -->|No| C[Log untracked dependency warning]
    C --> D[Continue checking dependencies]
    B -->|Yes| E{Versions match?}
    E -->|No| F[Log version mismatch warning]
    E -->|Yes| D
    F --> D
    D --> G[Load program or module state]
Loading

Reviews (1): Last reviewed commit: "fix(saving): tolerate unknown dependency..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant