Skip to content

Unresolved Models.Roles reference crashes netclaw doctor (exit 134); model list misdiagnoses it and directs operators there #1676

Description

@Aaronontheweb

Summary

A single typo in Models.Roles.Main makes both netclaw doctor and netclaw doctor --fix crash with an unhandled exception and exit 134 (SIGABRT) — and netclaw model list explicitly directs the operator to run exactly those two commands. The diagnostic path is a dead end precisely when it is needed.

Repro

Verified against netclaw 0.25.0-alpha.onnx.7 (commit 5c7278f) in an isolated NETCLAW_HOME. Config is structurally valid and parses fine; Roles.Main just names a definition that doesn't exist:

{
  "Providers": { "local": { "Type": "ollama", "BaseUrl": "http://localhost:11434" } },
  "Models": {
    "Definitions": { "local-qwen3-30b": { "Provider": "local", "ModelId": "qwen3:30b" } },
    "Roles": { "Main": "does-not-exist" }
  }
}

Step 1 — model list misdiagnoses and misdirects:

$ netclaw model list
Error: model configuration could not be parsed.
Run `netclaw doctor` to diagnose, or `netclaw doctor --fix` to repair it.
exit=1

The config did parse. The real error — Models:Roles:Main references unknown definition 'does-not-exist' — is produced by the resolver but caught and discarded at ModelCommand.cs:526-529.

Step 2 — the suggested command crashes:

$ netclaw doctor
Unhandled exception. System.InvalidOperationException: Models:Roles:Main references unknown definition 'does-not-exist'.
   at Netclaw.Configuration.ModelConfigurationResolver.ResolveDefinition(...)
   at Netclaw.Cli.Doctor.ContextWindowDoctorCheck.RunAsync(CancellationToken cancellationToken)
   at Netclaw.Cli.Doctor.DoctorRunner.RunAsync(CancellationToken cancellationToken)
exit=134

Step 3 — so does the repair command, after printing a diff implying it will write:

$ netclaw doctor --fix -y
  +   "Models": {
  +     "Definitions": { ... },
  +     "Roles": { "Main": "does-not-exist" }
  +   },
  + }
Fatal error — crash log written to /home/petabridge/.netclaw/logs/crash-20260716-110953.log
Unhandled exception. System.InvalidOperationException: Models:Roles:Main references unknown definition 'does-not-exist'.
exit=134

Config is unchanged afterward. netclaw status is unaffected (exit 0).

Three distinct defects

  1. Wrong diagnosis. model list reports "could not be parsed" for a config that parses. The accurate resolver message is swallowed at ModelCommand.cs:526-529.
  2. Wrong remediation. It points at doctor --fix, which only converts legacy shape to named shape. It cannot repair an unresolved reference within an already-canonical config, so the advice would be wrong even if it ran.
  3. Crash instead of report. ContextWindowDoctorCheck lets the resolver exception escape DoctorRunner. doctor is the tool of last resort for a broken config — it should be the one command that never dies on one.

Severity is amplified by the combination: the operator's only guidance leads to a core dump, with no message naming the offending role or definition.

Expected

  • model list surfaces the resolver's actual message (Models:Roles:Main references unknown definition 'does-not-exist'.).
  • doctor catches resolver failures and reports them as failed checks naming the role and the unknown definition.
  • Remediation text points at fixing the reference (or lists valid definition names), not at doctor --fix.

Test gap

Refresh_MissingNamedDefinition_SurfacesInvalidConfiguration (ModelManagerViewModelTests.cs:502) covers the TUI path only. There is no coverage for doctor or model list against an unresolved role reference.

Docs impact

netclaw-dev/netclaw-website#83 asks docs to state that model list reports unresolved config "with a clear error directing the operator to netclaw doctor / doctor --fix". That is not current behavior, and following it would send readers into a crash. Docs will document manual repair instead. Tracked in netclaw-dev/netclaw-website#86.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions