Skip to content

fix(runner): make RunnerContext.get_env() read live from os.environ#885

Merged
mergify[bot] merged 1 commit intomainfrom
fix/stale-runnercontext-env
Mar 11, 2026
Merged

fix(runner): make RunnerContext.get_env() read live from os.environ#885
mergify[bot] merged 1 commit intomainfrom
fix/stale-runnercontext-env

Conversation

@bobbravo2
Copy link
Copy Markdown
Member

@bobbravo2 bobbravo2 commented Mar 11, 2026

Summary

This is a followup PR to ensure that #726 data is pushed to Langfuse for product instrumentation

  • Fix stale environment snapshot in RunnerContext: get_env() was reading from a frozen dict captured once at construction. Runtime mutations to os.environ (by POST /workflow, POST /repos/add, auth refresh) were invisible to any code using context.get_env().
  • Root cause: __post_init__ merged os.environ into self.environment and get_env() read only from that dict. The context is never recreated — mark_dirty() resets the bridge but reuses the same stale context.
  • Fix: Store explicit constructor overrides in _overrides. get_env() now checks overrides first, then falls through to live os.environ. self.environment remains populated for backward compatibility.

Changes

File Change
ambient_runner/platform/context.py Store _overrides in __post_init__; get_env() reads live from os.environ with overrides winning
tests/test_context.py Regression tests: runtime mutation visibility + override precedence

Test plan

  • New test_get_env_sees_os_environ_mutations_after_creation — creates context, mutates os.environ after, asserts get_env() returns mutated value
  • New test_explicit_overrides_win_over_os_environ — constructor overrides take precedence even after os.environ mutation
  • All 73 existing tests pass without modification (test_context, test_bridge_claude, test_observability)
  • CI green

Made with Cursor

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 93c08729-5727-45a1-9881-bd328976dd46

📥 Commits

Reviewing files that changed from the base of the PR and between 9ca461a and 935dd40.

📒 Files selected for processing (2)
  • components/runners/ambient-runner/ambient_runner/platform/context.py
  • components/runners/ambient-runner/tests/test_context.py

Walkthrough

RunnerContext now stores constructor-provided environment overrides in an internal _overrides dict. get_env returns override values when present; for keys without overrides it reads current values from os.environ, so external environment mutations after context creation are visible for non-overridden keys.

Changes

Cohort / File(s) Summary
RunnerContext override behavior
components/runners/ambient-runner/ambient_runner/platform/context.py
Added internal _overrides storage for explicit environment overrides. get_env now returns stored overrides when present and otherwise reads live values from os.environ. Docstrings updated to describe new behavior.
RunnerContext get_env tests
components/runners/ambient-runner/tests/test_context.py
Added tests verifying that get_env reflects os.environ mutations for non-overridden keys and that constructor-provided overrides take precedence over os.environ, including after environment changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: making RunnerContext.get_env() read live from os.environ instead of from a stale snapshot.
Description check ✅ Passed The description is directly related to the changeset, explaining the root cause, the fix, files changed, and test plan for the stale environment snapshot issue in RunnerContext.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/stale-runnercontext-env

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@bobbravo2 bobbravo2 marked this pull request as ready for review March 11, 2026 17:05
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/runners/ambient-runner/ambient_runner/platform/context.py`:
- Around line 31-33: The bridge is still reading stale merged environment via
direct access to self._context.environment; update any reads in the LangGraph
bridge (where it reads LANGGRAPH_URL, LANGGRAPH_GRAPH_ID, LANGSMITH_API_KEY from
self._context.environment) to use the context's get_env() method (or the helper
in ambient_runner.platform.utils) instead so runtime-updated env vars are
respected; search for occurrences of self._context.environment in the bridge (or
the symbols LANGGRAPH_URL/LANGGRAPH_GRAPH_ID/LANGSMITH_API_KEY) and replace
those direct dict reads with self._context.get_env().get(...) or the utils
helper.
- Around line 32-39: get_env currently assumes self._overrides exists which
fails for objects created via object.__new__; update get_env (in the
RunnerContext / ambient_runner.platform.context module) to first check for the
presence of _overrides (e.g. via hasattr(self, "_overrides")) and if absent fall
back to using self.environment for override lookup, or ensure _overrides is
initialized (empty dict) before use; specifically modify get_env to return
self._overrides[key] when _overrides exists, otherwise check self.environment
for the key and then return os.environ.get(key, default).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 26a13632-9ea2-4df9-9a7c-ae0e5bd01483

📥 Commits

Reviewing files that changed from the base of the PR and between 744c0d4 and 9ca461a.

📒 Files selected for processing (2)
  • components/runners/ambient-runner/ambient_runner/platform/context.py
  • components/runners/ambient-runner/tests/test_context.py

@Gkrumbach07
Copy link
Copy Markdown
Contributor

Can you fix unit tests

RunnerContext.__post_init__ snapshots os.environ once at construction.
After that, get_env() reads from the frozen dict. Multiple endpoints
mutate os.environ at runtime (POST /workflow, POST /repos/add,
auth refresh), but the context is never recreated — mark_dirty()
resets the bridge while reusing the same stale context.

Store explicit constructor overrides separately in _overrides and
make get_env() check overrides first, then fall through to live
os.environ. self.environment remains populated for backward compat.

Made-with: Cursor
@bobbravo2 bobbravo2 force-pushed the fix/stale-runnercontext-env branch from 9ca461a to 935dd40 Compare March 11, 2026 18:30
@bobbravo2
Copy link
Copy Markdown
Member Author

Can you fix unit tests

Pushed!

Problem was: "The issue was that test_claude_auth.py has a _make_context() helper that uses object.new(RunnerContext) to bypass post_init, so _overrides was never set. The fix adds a getattr guard: when _overrides is absent (bypassed init), get_env() falls back to the old behavior of reading only from self.environment. When _overrides is present (normal construction), it checks overrides first, then reads live from os.environ."

@ambient-code ambient-code bot added this to the Merge Queue milestone Mar 11, 2026
mergify bot added a commit that referenced this pull request Mar 11, 2026
@mergify mergify bot merged commit 1ed7618 into main Mar 11, 2026
26 checks passed
@mergify mergify bot deleted the fix/stale-runnercontext-env branch March 11, 2026 20:08
@mergify
Copy link
Copy Markdown

mergify bot commented Mar 11, 2026

Merge Queue Status

This pull request spent 19 seconds in the queue, including 5 seconds running CI.

Required conditions to merge

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.

2 participants