Skip to content

fix: propagate the API run id to the tracker - #1327

Open
davidberenstein1957 wants to merge 3 commits into
masterfrom
fix/api-run-id-never-propagates
Open

davidberenstein1957 wants to merge 3 commits into
masterfrom
fix/api-run-id-never-propagates

Conversation

@davidberenstein1957

@davidberenstein1957 davidberenstein1957 commented Aug 12, 2026 •

Copy link
Copy Markdown
Collaborator

Description

EmissionsTracker.run_id used to start as a locally generated uuid and never got updated once the API created its own run id, because CodeCarbonAPIOutput creates the API run lazily and nothing wrote the resulting id back onto the tracker. This PR moves the API run creation into start() and makes run_id switch to the API run id as soon as it exists. If the API is down at start(), run_id switches as soon as a later emission creates the run, with a warning that earlier records used the local id.

Related Issue

Fixes #1303

Motivation and Context

With OutputMethod.API enabled, tracker.run_id stayed None and _prepare_emissions_data recorded the literal string "None" in every row. This broke joining CSV data with API data, broke on_csv_write="update" (it matched on "None" and overwrote the previous run's row), and caused per-task / BOAMPS filenames to collide on ..._None.csv.

How Has This Been Tested?

tests/test_emissions_tracker.py::TestCarbonTracker::test_run_id_with_api_output_is_never_none asserts tracker.run_id is not None and that the run id written to emissions.csv matches the API run id. It fails on master and passes with this change.

uv run pytest tests/test_emissions_tracker.py tests/output_methods tests/test_tracking_inference.py tests/test_api_call.py -q passes locally.

Screenshots (if appropriate):

N/A

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

AI Usage Disclosure

  • 🟥 AI-vibecoded: You cannot explain the logic. Car analogy : the car drive by itself, you are outside it and just tell it where to go.
  • 🟠 AI-generated: Car analogy : the car drive by itself, you are inside and give instructions.
  • ⭐ AI-assisted. Car analogy : you drive the car, AI help you find your way.
  • ♻️ No AI used. Car analogy : you drive the car.

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the docs/how-to/contributing.md document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@codecov

codecov Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.77%. Comparing base (e5e46ab) to head (d53e2de).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1327      +/-   ##
==========================================
+ Coverage   91.70%   91.77%   +0.07%     
==========================================
  Files          49       49              
  Lines        5157     5169      +12     
==========================================
+ Hits         4729     4744      +15     
+ Misses        428      425       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@davidberenstein1957
davidberenstein1957 marked this pull request as ready for review August 12, 2026 19:14
@davidberenstein1957
davidberenstein1957 requested a review from a team as a code owner August 12, 2026 19:14
The tracker generated its own run_id and never picked up the one the API
created, so API-backed runs persisted a local uuid (or the string "None")
instead of the run id the server knows about.

Create the API run in start(), where the output handler is already wired,
and adopt its run id when there is one. run_id stays a plain writable
attribute.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@davidberenstein1957
davidberenstein1957 force-pushed the fix/api-run-id-never-propagates branch from 08cdabf to 0221c73 Compare August 19, 2026 14:01
@benoit-cty

Copy link
Copy Markdown
Contributor

🤖 This review comment was written and posted by Claude Opus 5.5 (AI assistant), at the request of @benoit-cty. Findings were checked by reading the code and running tests locally (merged with current master where relevant), but please double-check before acting on them.

Verdict: ✅ Approve with one fix suggested

The bug is real. With API output, tracker.run_id stays None, so every CSV row gets the string "None". The new tests fail on master. The API run is now created in start(), with a fallback to a locally generated id if that fails. Each tracker has its own API output, so multiple trackers are fine.

Issue to fix: CSV and API ids can still differ (medium)

  • If the API is down at start(), run_id keeps the local id (emissions_tracker.py ~L712-719).
  • Later, _emit() calls _ensure_api_run() (output_methods/http.py L60-63), which creates the API run once the API is back, with a different id from every CSV row. This happens silently, and defeats the goal of "a single id everywhere".
  • Suggested fix: when the API run is eventually created, sync self.run_id from _api_output.run_id, e.g. in _prepare_emissions_data, and log once that earlier CSV rows used the local id. Or, if the API accepts a client-supplied run id, create the run with the local id.
  • Please add a test: API fails at start(), recovers at the first _emit(), then assert the ids agree afterwards.

Nits:

  1. start() now makes a blocking HTTP POST (2 s timeout) on the caller's thread. That's acceptable, but worth a line in the docs.
  2. A ConnectionError is logged twice, once in _create_run and once in start().
  3. run_id read before start() differs from the one after. Document this or keep it consistent.
  4. The description mentions a run_id property that isn't in the code; please update it.
  5. The branch is behind master; please update it.

davidberenstein1957 and others added 2 commits September 23, 2026 16:36
Log the start() fallback once as a warning, and document the blocking
run creation and the run_id switch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@davidberenstein1957

Copy link
Copy Markdown
Collaborator Author

Made the changes in d53e2de: run_id now syncs to the API run once it's created late (with a test for API down at start then recovering), the start() fallback logs once as a warning, docs mention the blocking call and the run_id switch, PR description fixed, and master merged in.

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tracker.run_id stays None when OutputMethod.API is enabled, CSV rows record run_id="None"

2 participants