Problem
When llama.cpp runs in router mode, the /v1/models and /props endpoints do not populate context window metadata. The probe returns n_ctx: 0 (unset/sentinel value), which NetClaw treats as a legitimate context window of 0 tokens.
Root Cause
ProbeHelpers.TryReadInt32() returns the raw integer value when present — including 0:
internal static int? TryReadInt32(JsonElement element, string propertyName)
{
return element.TryGetProperty(propertyName, out var property) &&
property.ValueKind == JsonValueKind.Number &&
property.TryGetInt32(out var value)
? value // returns 0, not null!
: null;
}
Then in ModelCapabilityResolution.ResolveModelCapabilities(), the validation check:
if (model.ContextWindow is int configured
&& detected?.ContextWindowTokens is int detected // 0 matches is int!
&& configured > detected) // 120000 > 0 → throws
{
throw new InvalidOperationException(
$"Models:Main:ContextWindow ({configured}) exceeds the " +
$"provider-reported effective context window ({detected}).");
}
is int matches 0 as a valid integer, so the validation incorrectly concludes the user-set context window exceeds the provider-reported value.
Impact
- Users running llama.cpp in router mode see startup failures with confusing error messages
- Users running llama.cpp with models that expose
n_ctx: 0 in metadata hit the same issue
- The error message says to "Reduce the configured ContextWindow" — but the real fix is either setting a correct
ContextWindow in config OR fixing the zero-detection logic
Reproduction
- Start llama.cpp in router mode (e.g.,
llama-router)
- Configure NetClaw with a model that has an explicit
ContextWindow set
- Observe: daemon refuses to start with "ContextWindow exceeds the provider-reported effective context window (0)"
Proposed Fix
Either:
- In
TryReadInt32: Return null when the parsed value is 0 (value > 0 guard)
- In
LlamaCppBackendStrategy: Treat n_ctx == 0 as "not reported" and return null
- In
ModelCapabilityResolution: Skip the validation check when detectedContextWindow == 0
Option 1 is the cleanest since n_ctx: 0 in llama.cpp always means "unset" — it is never a legitimate context window size.
Tweet Reference
User reported: https://x.com/rare47/status/2061456687500775842
Problem
When llama.cpp runs in router mode, the
/v1/modelsand/propsendpoints do not populate context window metadata. The probe returnsn_ctx: 0(unset/sentinel value), which NetClaw treats as a legitimate context window of 0 tokens.Root Cause
ProbeHelpers.TryReadInt32()returns the raw integer value when present — including0:Then in
ModelCapabilityResolution.ResolveModelCapabilities(), the validation check:is intmatches0as a valid integer, so the validation incorrectly concludes the user-set context window exceeds the provider-reported value.Impact
n_ctx: 0in metadata hit the same issueContextWindowin config OR fixing the zero-detection logicReproduction
llama-router)ContextWindowsetProposed Fix
Either:
TryReadInt32: Returnnullwhen the parsed value is0(value > 0guard)LlamaCppBackendStrategy: Treatn_ctx == 0as "not reported" and returnnullModelCapabilityResolution: Skip the validation check whendetectedContextWindow == 0Option 1 is the cleanest since
n_ctx: 0in llama.cpp always means "unset" — it is never a legitimate context window size.Tweet Reference
User reported: https://x.com/rare47/status/2061456687500775842