mlco2 / mlco2/codecarbon

OfflineEmissionsTracker silently returns a half-built object when construction fails

Open Beginner friendly
#1,311 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.9k
Forks
323
Avg merge
1d 12h
Merged PRs (30d)
12

Description

When OfflineEmissionsTracker is constructed with an invalid configuration, no exception is raised. The constructor returns a partially initialised object, every subsequent call fails silently, and the run produces no emissions data at all. The online EmissionsTracker raises correctly for the same input, so the two constructors have opposite error semantics.

Reproduction

from codecarbon import OfflineEmissionsTracker

tracker = OfflineEmissionsTracker(country_iso_code="FRA", output_dir="/does/not/exist")
tracker.start()
# ... user workload ...
print(tracker.stop())   # None, and emissions.csv was never written

EmissionsTracker(output_dir="/does/not/exist") raises OSError: Folder ... does not exist ! as expected.

Root cause

OfflineEmissionsTracker.__init__ is decorated with @suppress(Exception) at codecarbon/emissions_tracker.py:1312. The validation in BaseEmissionsTracker._set_from_conf (codecarbon/emissions_tracker.py:138-140) raises OSError, but the decorator swallows it, so super().__init__ never reaches _initialize_runtime_state() / _initialize_scheduler_state() (codecarbon/emissions_tracker.py:603-604). The object then has no _start_time, _hardware, _scheduler or _output_handlers.

start() and stop() are also @suppress(Exception) (lines 692 and 886), so the resulting AttributeError: OfflineEmissionsTracker object has no attribute _start_time is downgraded to warnings as well. Under the CLI default log_level="error" (codecarbon/cli/main.py) nothing is printed at all.

suppress itself lives at codecarbon/core/util.py:21-30.

Expected vs actual

  • Expected: a misconfigured offline tracker raises at construction time, like the online tracker does.
  • Actual: construction succeeds, start()/stop() no-op with warnings, stop() returns None, and no emissions file is produced. Users reasonably conclude CodeCarbon does not work on their machine.

Suppressing exceptions in start/flush/stop is deliberate and should stay: CodeCarbon must never crash a training job at runtime. The decorator on the constructor is a different case, since failure there means the object invariants were never established.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in codecarbon/emissions_tracker.py at OfflineEmissionsTracker.init around line 1312, then compare it with EmissionsTracker and inspect BaseEmissionsTracker._set_from_conf around lines 138-140. Reproduce the invalid output_dir case and verify that construction raises while the deliberate runtime suppression in start and stop remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.