Summary
The guard that blocks model-config migration while legacy NETCLAW_Models__Main__* environment overrides are present is correct in intent but surfaces as an unhandled exception — stack trace, crash log, and exit 134 (SIGABRT) instead of a clean CLI error.
Repro
Verified against netclaw 0.25.0-alpha.onnx.7 (commit 5c7278f) in an isolated NETCLAW_HOME.
Legacy-shape config:
{
"Providers": { "local": { "Type": "ollama", "BaseUrl": "http://localhost:11434" } },
"Models": { "Main": { "Provider": "local", "ModelId": "qwen3:30b" } }
}
Then:
$ export NETCLAW_Models__Main__ContextWindow="65536"
$ netclaw model set main local qwen3:8b
Fatal error — crash log written to /home/petabridge/.netclaw/logs/crash-20260716-110951.log
Unhandled exception. System.InvalidOperationException: Cannot migrate Models while legacy environment override 'NETCLAW_Models__Main__ContextWindow' is set. Move model overrides to NETCLAW_Models__Definitions__<name>__* and NETCLAW_Models__Roles__* first.
at Netclaw.Cli.Config.ConfigFileHelper.PreserveLegacyModelsBackup(String path, Dictionary`2 data)
at Netclaw.Cli.Config.ConfigFileHelper.WriteConfigFile(String path, Dictionary`2 data)
at Netclaw.Cli.Model.ModelCommand.RunSetAsync(String[] args, NetclawPaths paths, IProviderProbe probe, TextWriter writer)
...
exit=134
Expected
The message itself is good — accurate, actionable, names the offending variable and the fix. It should print as Error: ... and exit 1, consistent with every other model set validation failure (unknown provider, invalid modalities, conflicting flags).
Cause
RunSetAsync has no try/catch around WriteConfigFile (ModelCommand.cs:283). The guard throws from ConfigFileHelper.cs:183-186 (and DoctorFixService.cs:73-76 on the doctor --fix path).
Correctness note
The guard works: config was not rewritten and no partial state was left behind. This is purely a presentation defect — but exit 134 + a crash log reads as "netclaw broke" rather than "your environment needs a change", and it pollutes the crash-log directory with entries that aren't crashes.
Aside (minor, possibly separate)
The crash log was written to /home/petabridge/.netclaw/logs/ even though NETCLAW_HOME pointed at a sandbox — crash logging appears not to respect NETCLAW_HOME. Noting here rather than filing separately; happy to split out.
Docs impact
netclaw-dev/netclaw-website#83 asks docs to cover the env-var migration guard. Docs will state the guard exists and quote the message, but cannot present it as a clean error path until this is fixed. Tracked in netclaw-dev/netclaw-website#86.
Summary
The guard that blocks model-config migration while legacy
NETCLAW_Models__Main__*environment overrides are present is correct in intent but surfaces as an unhandled exception — stack trace, crash log, and exit 134 (SIGABRT) instead of a clean CLI error.Repro
Verified against
netclaw 0.25.0-alpha.onnx.7 (commit 5c7278f)in an isolatedNETCLAW_HOME.Legacy-shape config:
{ "Providers": { "local": { "Type": "ollama", "BaseUrl": "http://localhost:11434" } }, "Models": { "Main": { "Provider": "local", "ModelId": "qwen3:30b" } } }Then:
Expected
The message itself is good — accurate, actionable, names the offending variable and the fix. It should print as
Error: ...and exit 1, consistent with every othermodel setvalidation failure (unknown provider, invalid modalities, conflicting flags).Cause
RunSetAsynchas no try/catch aroundWriteConfigFile(ModelCommand.cs:283). The guard throws fromConfigFileHelper.cs:183-186(andDoctorFixService.cs:73-76on thedoctor --fixpath).Correctness note
The guard works: config was not rewritten and no partial state was left behind. This is purely a presentation defect — but exit 134 + a crash log reads as "netclaw broke" rather than "your environment needs a change", and it pollutes the crash-log directory with entries that aren't crashes.
Aside (minor, possibly separate)
The crash log was written to
/home/petabridge/.netclaw/logs/even thoughNETCLAW_HOMEpointed at a sandbox — crash logging appears not to respectNETCLAW_HOME. Noting here rather than filing separately; happy to split out.Docs impact
netclaw-dev/netclaw-website#83 asks docs to cover the env-var migration guard. Docs will state the guard exists and quote the message, but cannot present it as a clean error path until this is fixed. Tracked in netclaw-dev/netclaw-website#86.