Skip to content

fix(flags): interpret bare numeric timeout as seconds - #1675

Merged
nicholas-fedor merged 2 commits into
mainfrom
fix/set-bare-duration-to-seconds
May 27, 2026
Merged

fix(flags): interpret bare numeric timeout as seconds#1675
nicholas-fedor merged 2 commits into
mainfrom
fix/set-bare-duration-to-seconds

Conversation

@nicholas-fedor

@nicholas-fedor nicholas-fedor commented May 27, 2026

Copy link
Copy Markdown
Owner

This PR fixes container restart failures when WATCHTOWER_TIMEOUT is set as a bare number (e.g., 60).

Problem

Setting WATCHTOWER_TIMEOUT=60 was interpreted as 60 nanoseconds instead of 60 seconds by viper/cast, causing immediate context deadline exceeded errors during container creation. Users reported containers failing to restart after updates (see #1664).

Solution

Pre-parse bare numeric values in envDuration before viper/cast processes them (which would otherwise interpret bare numbers as nanoseconds).

Changes

  • Added isPureNumeric helper to detect bare integer/float values without duration units
  • Added early return in envDuration for bare numeric values, interpreting them as seconds
  • Added TestIsPureNumeric table-driven tests
  • Added TestEnvDuration_LegacyBareNumberAsSeconds table-driven tests
  • Added FuzzIsPureNumeric fuzz test for invariant verification
  • Documented bare numeric interpretation in timeout flag docs

Summary by CodeRabbit

  • Documentation

    • Clarified timeout interpretation: bare numeric values (e.g., 60, 1.5) are treated as seconds; explicit unit suffixes required for other time units.
  • Behavior

    • Environment timeout parsing now reliably accepts bare integers and fractional seconds, trims whitespace and signed values, and handles out-of-range inputs predictably.
  • Tests

    • Added comprehensive unit and fuzz tests covering numeric parsing, edge cases, and legacy bare-number-as-seconds behavior.

Review Change Stack

- Add isPureNumeric helper for bare integer/float detection
- Pre-parse bare values in envDuration before viper/cast processes them
- Add table-driven tests for isPureNumeric and envDuration
- Add fuzz test for isPureNumeric invariant verification
- Document bare numeric interpretation in timeout flag docs
@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/flags/flags.go 93.33% 1 Missing and 1 partial ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1675      +/-   ##
==========================================
+ Coverage   74.60%   74.68%   +0.08%     
==========================================
  Files          59       59              
  Lines        9839     9878      +39     
==========================================
+ Hits         7340     7377      +37     
- Misses       2237     2238       +1     
- Partials      262      263       +1     
Files with missing lines Coverage Δ
internal/flags/flags.go 86.21% <93.33%> (+0.26%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codacy-production

codacy-production Bot commented May 27, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 2 medium

Alerts:
⚠ 2 issues (≤ 0 issues of at least minor severity)

Results:
2 new issues

Category Results
Complexity 2 medium

View in Codacy

🟢 Metrics 30 complexity · 0 duplication

Metric Results
Complexity 30
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a46b45b-f299-42b8-bb0a-711c66b2c585

📥 Commits

Reviewing files that changed from the base of the PR and between f12a7f5 and 3fc333d.

📒 Files selected for processing (2)
  • internal/flags/flags.go
  • internal/flags/flags_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/flags/flags.go
  • internal/flags/flags_test.go

Walkthrough

This PR treats bare numeric environment values for duration flags as seconds by adding a preprocessing step in envDuration that detects pure numeric strings, parses them as floats (seconds), clamps overflow, and falls back to viper.GetDuration for non-numeric/unit-suffixed inputs. Tests, a fuzz test, and docs were added.

Changes

Bare Numeric Duration Timeout Parsing

Layer / File(s) Summary
Core duration parsing and numeric validation
internal/flags/flags.go
envDuration now reads the raw env var, treats pure numeric strings (validated by isPureNumeric) as seconds by parsing with strconv.ParseFloat and converting with time.Second, and clamps to time.Duration bounds; isPureNumeric was added and math/strconv imports introduced.
Unit tests for legacy bare number handling and numeric validation
internal/flags/flags_test.go
Adds TestEnvDuration_LegacyBareNumberAsSeconds validating integers, fractional seconds, explicit unit suffixes, whitespace/signs, invalid inputs, and overflow/clamping; adds TestIsPureNumeric covering accepted and rejected numeric string forms; imports math and time for expectations.
Fuzz test for numeric validation
internal/flags/flags_fuzz_test.go
Adds FuzzIsPureNumeric which seeds numeric and invalid inputs, ensures isPureNumeric doesn't panic, and when true asserts strconv.ParseFloat yields finite values or only range errors.
User-facing documentation update
docs/configuration/arguments/index.md
Doc note clarifies that bare numeric timeout values (e.g., 60, 1.5) are interpreted as seconds and other units require explicit unit suffixes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: implementing logic to interpret bare numeric timeout values as seconds instead of nanoseconds, which is the core fix addressing issue #1664.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/flags/flags.go`:
- Around line 616-619: The float-to-duration conversion using time.Duration(val
* float64(time.Second)) must be guarded against int64 overflow; compute nanos :=
val * float64(time.Second) and check against float64(math.MaxInt64) and
float64(math.MinInt64) (import math), then if nanos exceeds those bounds clamp
to math.MaxInt64 or math.MinInt64 (or return an error per surrounding
convention) before converting to time.Duration; update the strconv.ParseFloat
branch (the val variable and conversion expression) to perform this bounds check
and safe conversion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0a2a13b4-1766-41fd-b684-43b4bcd83ac8

📥 Commits

Reviewing files that changed from the base of the PR and between 1baa9b5 and f12a7f5.

📒 Files selected for processing (4)
  • docs/configuration/arguments/index.md
  • internal/flags/flags.go
  • internal/flags/flags_fuzz_test.go
  • internal/flags/flags_test.go

Comment thread internal/flags/flags.go
- Add overflow checks before converting float64 nanoseconds to time.Duration
- Clamp values exceeding int64 range to math.MaxInt64 or math.MinInt64
- Update test to expect MaxInt64 clamping instead of zero fallback for very large values
- Add test case for explicit overflow clamping behavior
@nicholas-fedor
nicholas-fedor merged commit 8581090 into main May 27, 2026
19 of 20 checks passed
@nicholas-fedor
nicholas-fedor deleted the fix/set-bare-duration-to-seconds branch May 27, 2026 09:35
@nicholas-fedor nicholas-fedor linked an issue May 27, 2026 that may be closed by this pull request
3 tasks
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.

[Bug]: error=failed to create container / context deadline exceeded

1 participant