Skip to content

fix(entrypoint): gracefully skip invalid overrides instead of hard-exit - #2700

Merged
cv merged 1 commit into
mainfrom
fix/2698-runtime-overrides-graceful-reject
Apr 29, 2026
Merged

fix(entrypoint): gracefully skip invalid overrides instead of hard-exit#2700
cv merged 1 commit into
mainfrom
fix/2698-runtime-overrides-graceful-reject

Conversation

@jyaunches

@jyaunches jyaunches commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #2698runtime-overrides-e2e test 14 crashes because invalid override validation uses return 1, which under set -euo pipefail kills the container before CMD runs.

Root Cause

PR #2659 tightened the trigger guard for apply_model_override() but kept return 1 for validation failures. When NEMOCLAW_CONTEXT_WINDOW=notanumber is rejected, return 1 propagates through set -e and exits the entrypoint. The container dies before the test can read the config.

Fix

Change non-security-critical validation failures from return 1 to return 0:

  • Invalid API type → skip, don't crash
  • Non-integer context window → skip, don't crash
  • Non-integer max tokens → skip, don't crash
  • Invalid reasoning boolean → skip, don't crash
  • Non-http CORS origin → skip, don't crash

Security-critical rejections remain return 1:

  • Symlink on config/hash path (indicates tampering)
  • Control characters in model override (indicates injection)
  • Oversized model override (indicates injection)

The security warning is still logged to stderr, but the container starts normally with config unchanged.

Verification

  • Unit tests pass (test/nemoclaw-start.test.ts — assertions use toContain on message strings which are preserved)
  • runtime-overrides-e2e passes (to be validated on sparky)

AI Disclosure

  • AI-assisted — tool: Claude Code (pi agent)

Signed-off-by: Julie Yaunches jyaunches@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved startup resilience by gracefully handling invalid configuration parameters. The system now logs warnings and continues instead of aborting when misconfigured environment variables are detected.

Validation failures for non-security-critical overrides (malformed integers,
invalid boolean, invalid API type, non-http CORS origin) now return 0 instead
of return 1. Under set -e, return 1 killed the container before CMD could run,
breaking the runtime-overrides E2E test 14 which expects to read unchanged
config after a rejected override.

Security-critical rejections (symlinks, control characters) remain return 1
since those indicate real tampering attempts.

Fixes #2698

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e6957a74-fcdd-41c8-bd77-6e1dc9262c50

📥 Commits

Reviewing files that changed from the base of the PR and between 24725d2 and 1d5894e.

📒 Files selected for processing (1)
  • scripts/nemoclaw-start.sh

📝 Walkthrough

Walkthrough

The pull request modifies validation error handling in the entrypoint script. When environment variable validation fails for model/API parameters and CORS origin, the script now logs a warning and continues startup instead of exiting with failure, preserving build-time defaults and preventing container abort.

Changes

Cohort / File(s) Summary
Entrypoint Validation Logic
scripts/nemoclaw-start.sh
Modified apply_model_override() and apply_cors_override() to return success (0) on non-security-critical validation failures (malformed integers, invalid booleans, invalid API types) instead of return 1. Functions now log "— skipping override" warnings to stderr and allow startup to proceed with unmodified config.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit hops with glee so bright,
For now the startup gets it right!
Bad numbers don't cause crash and burn,
Just skip and safely, homeward turn. 🏡✨

🚥 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 title accurately summarizes the main change: making invalid overrides skip gracefully instead of hard-exiting the entrypoint.
Linked Issues check ✅ Passed The PR fully addresses #2698 objectives: non-security validation failures now return 0 instead of 1, logging warnings while allowing container startup with unchanged config.
Out of Scope Changes check ✅ Passed All changes are directly scoped to addressing #2698: modified only the error handling behavior for validation failures in nemoclaw-start.sh.
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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/2698-runtime-overrides-graceful-reject

Review rate limit: 8/10 reviews remaining, refill in 10 minutes and 5 seconds.

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

@cv
cv merged commit 97202de into main Apr 29, 2026
19 checks passed
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
…it (NVIDIA#2700)

## Summary

Fixes NVIDIA#2698 — `runtime-overrides-e2e` test 14 crashes because invalid
override validation uses `return 1`, which under `set -euo pipefail`
kills the container before CMD runs.

## Root Cause

PR NVIDIA#2659 tightened the trigger guard for `apply_model_override()` but
kept `return 1` for validation failures. When
`NEMOCLAW_CONTEXT_WINDOW=notanumber` is rejected, `return 1` propagates
through `set -e` and exits the entrypoint. The container dies before the
test can read the config.

## Fix

Change non-security-critical validation failures from `return 1` to
`return 0`:
- Invalid API type → skip, don't crash
- Non-integer context window → skip, don't crash
- Non-integer max tokens → skip, don't crash
- Invalid reasoning boolean → skip, don't crash
- Non-http CORS origin → skip, don't crash

Security-critical rejections remain `return 1`:
- Symlink on config/hash path (indicates tampering)
- Control characters in model override (indicates injection)
- Oversized model override (indicates injection)

The security warning is still logged to stderr, but the container starts
normally with config unchanged.

## Verification
- [x] Unit tests pass (`test/nemoclaw-start.test.ts` — assertions use
`toContain` on message strings which are preserved)
- [ ] `runtime-overrides-e2e` passes (to be validated on sparky)

## AI Disclosure
- [x] AI-assisted — tool: Claude Code (pi agent)

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved startup resilience by gracefully handling invalid
configuration parameters. The system now logs warnings and continues
instead of aborting when misconfigured environment variables are
detected.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
ericksoa pushed a commit that referenced this pull request May 3, 2026
…2842)

## Summary

Resolves #2762. The Dockerfile build invokes
`scripts/generate-openclaw-config.py` once at image build time to bake
`openclaw.json`. Two of the build args it consumes
(`NEMOCLAW_CONTEXT_WINDOW`, `NEMOCLAW_MAX_TOKENS`) were coerced via an
unguarded `int(env.get(...))`, so a non-numeric, zero, or negative
`--build-arg` would surface a Python traceback and abort the build
instead of skipping the override the way PR #2700 made the runtime
entrypoint behave.

This change mirrors the runtime-entrypoint pattern: log a `[SECURITY]
... — skipping override, falling back to default` warning to stderr and
use the documented default. Empty-string overrides also fall back to the
default now, consistent with `NEMOCLAW_PROXY_HOST` /
`NEMOCLAW_PROXY_PORT`.

## Related Issue

Resolves #2762

## Changes

- `scripts/generate-openclaw-config.py`: new private helper
`_coerce_positive_int(env, name, default)` that returns the parsed value
when it is a positive integer string, otherwise emits the `[SECURITY]`
warning and returns the default. Both `NEMOCLAW_CONTEXT_WINDOW` (default
131072) and `NEMOCLAW_MAX_TOKENS` (default 4096) now route through it.
- `test/generate-openclaw-config.test.ts`: 8 new tests — 2 empty-string
fallback cases (matching the existing `NEMOCLAW_PROXY_*` empty-string
suite) plus 6 invalid-value cases (`notanumber`, `0`, `-1` for each var)
that assert both the fallback value lands in the generated config AND
the `[SECURITY]` warning text appears on stderr.

## Type of Change

- [X] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification

- [X] `npx prek run --all-files` passes
- [X] `npm test` passes (38/38 in `generate-openclaw-config.test.ts`,
112/112 in `nemoclaw-start.test.ts`)
- [X] Tests added or updated for new or changed behavior
- [X] No secrets, API keys, or credentials committed
- [ ] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

## AI Disclosure

- [X] AI-assisted — tools: Claude Code, OpenAI Codex

---
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Validation tightened for context window and max token settings: only
strictly positive integers are accepted. Empty, non-numeric, zero,
negative, or excessively large values now trigger a security warning to
stderr and revert to safe defaults.

* **Tests**
* Added tests covering empty, non-numeric, zero/negative, and oversized
environment inputs to verify warnings and fallback behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
cjagwani added a commit that referenced this pull request May 5, 2026
Stress-test against 5 historical NemoClaw cases surfaced two real spec
gaps that produced incorrect classifications:

1. Evidence-required filter was too strict for partial-fix detection.
   The LLM couldn't cite "PR diff line" when the gap is what the PR
   did NOT touch. Extended evidence to three citation shapes:
   - DIRECT (original): cite specific PR line + issue symptom
   - BY-OMISSION: cite PR scope + issue symptom showing same bug class
     in different instances PR did not touch (catches partial-fix)
   - FOLLOW-ON: cite the symbol/file PR introduced + issue's request
     to harden the same code (catches "PR introduced X, now harden X")

2. ADJACENT_FIX wording assumed the issue was already broken and the
   PR resolves it. Reframed to also include "PR opens a clear follow-on
   path on the same code the PR just touched" — covers the common
   pattern where an issue requests hardening of code a PR just
   introduced.

Test cases that drove these patches:
- #2700#2762 (partial-fix, was failing — now passes via by-omission)
- #2696#2875 (follow-on hardening, was ambiguous — now explicit)
@wscurran wscurran added the bug-fix PR fixes a bug or regression label Jun 8, 2026
@jyaunches
jyaunches deleted the fix/2698-runtime-overrides-graceful-reject branch June 12, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(e2e): runtime-overrides-e2e test 14 fails — entrypoint hard-exits on invalid override

3 participants