Custom (--from) sandboxes never reconcile openclaw.json with the routed model: startup fixes are root-gated and reconcile skips contextWindow/maxTokens
Problem Statement
A sandbox onboarded with --provider custom --from <custom Dockerfile> keeps the base image's generated model config in /sandbox/.openclaw/openclaw.json. Observed with model aws/anthropic/bedrock-claude-opus-4-8: the gateway route is correct (openshell inference get reports opus), but the config still holds agents.defaults.model.primary = inference/nvidia/nemotron-3-super-120b-a12b, contextWindow = 131072, maxTokens = 4096. The stale name is cosmetic (the gateway substitutes); the limits are not — OpenClaw uses them for output capping and compaction, so the agent is capped at nemotron's 4096 output tokens and compacts against a 131k window while actually talking to opus.
Cause chain:
openclaw.jsonis generated at base-image build from build ARGs; a--fromcustom stage cannot re-run the generator (post-generator attestation), so the custom image inherits the base's generated config.- The startup fixes exist —
apply_model_override()andreconcile_agent_model_with_provider()(#3175) innemoclaw-start.sh— but both return early unless running as root. Managed images get root startup from their driver; a--fromimage must end with a non-rootUSER(OpenShell rejects a root OCI image user for custom sandboxes), so under the Docker driver both functions silently no-op and nothing ever corrects the file. - Additionally, even in root mode,
reconcile_agent_model_with_provideronly syncs the model name/id — it never correctscontextWindow/maxTokens, andopenshell inference get --jsondoes not expose them, so there is no in-sandbox source of truth for limits.
Desired Behavior
- The startup reconcile/override should work for non-root custom sandboxes — e.g. gate on config writability (owner match) instead of
id -u, or have the Docker driver grant custom sandboxes the same startup treatment managed images get. - The reconcile should also address stale generated limits when the served model differs from the generated one (correct them from a trustworthy source, or drop the per-model keys so OpenClaw's catalog correction and defaults apply), and
openshell inference get --jsonideally exposes the route's context window / max output tokens so a reconcile has ground truth. - At minimum: a loud diagnostic instead of a silent no-op, so operators learn the config was not reconciled.
Reproduction
nemoclaw onboard --provider custom --model aws/anthropic/bedrock-claude-opus-4-8 --from <Dockerfile ending "USER sandbox"> (Docker driver) → compare openshell inference get with agents.defaults.model.primary and models.providers.inference.models[0].{contextWindow,maxTokens} in /sandbox/.openclaw/openclaw.json.
Workaround
The VSS blueprint's harness image now ships its own fail-open startup reconcile executed as the sandbox user (safe there because that image makes openclaw.json sandbox-owned for its plugin flow): name sync mirroring #3175's write shape, plus dropping the baked contextWindow/maxTokens when the served model differs from the generated one — see NVIDIA-AI-Blueprints/video-search-and-summarization#2222. A first-party fix would let us delete that.
Category
sandbox startup / custom images / model configuration.
Source: NVIDIA/NemoClaw