{"record":{"id":"3e6486888879e1c5","repo":"OrchardCMS/OrchardCore","slug":"cannot-convert-value-to-sbyte","errorCode":null,"errorMessage":"Cannot convert {value} to SByte","messagePattern":"Cannot convert (.+?) to SByte","errorType":"exception","errorClass":"InvalidCastException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs","lineNumber":395,"sourceCode":"    {\n        return value?._jsonValue?.GetValue<int?>();\n    }\n\n    public static explicit operator long(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<long>()\n            ?? throw new InvalidCastException($\"Cannot convert {value} to Int64\");\n    }\n\n    public static explicit operator long?(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<long?>();\n    }\n\n    public static explicit operator sbyte(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<sbyte>()\n            ?? throw new InvalidCastException($\"Cannot convert {value} to SByte\");\n    }\n\n    public static explicit operator sbyte?(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<sbyte?>();\n    }\n\n    public static explicit operator float(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<float>()\n            ?? throw new InvalidCastException($\"Cannot convert {value} to Float\");\n    }\n\n    public static explicit operator float?(JsonDynamicValue value)\n    {\n        return value?._jsonValue?.GetValue<float?>();\n    }\n","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs#L377-L413","documentation":"JsonDynamicValue wraps a JSON value and exposes explicit conversion operators for primitive types. The explicit operator sbyte casts _jsonValue.GetValue<sbyte>(); if the underlying JSON value is absent, null, or not representable as an SByte, the operator returns null and throws InvalidCastException with 'Cannot convert {value} to SByte'. It signals that the requested numeric conversion is not possible for the wrapped JSON token.","triggerScenarios":"Casting a JsonDynamicValue instance to sbyte with (sbyte)jsonDynamicValue when the wrapped JSON token is null, not a number, or a number outside the SByte range (-128..127), causing GetValue<sbyte>() to yield null.","commonSituations":"Reading small flags/ratings from JSON where the value is a string or exceeds 127, casting on a JsonDynamicValue built from a null token, or data contract changes shrinking the expected type to sbyte while producers still emit larger values.","solutions":["Cast to sbyte? (explicit operator sbyte?) instead of sbyte, which returns null instead of throwing, then handle the null case.","Validate the JSON value's numeric type and range (-128..127) with TryGetValue before casting.","Cast to a wider type (short/int) first if the data may exceed the sbyte range, and range-check explicitly.","Wrap the cast in try/catch for InvalidCastException if the value is genuinely optional."],"exampleFix":"// before\nsbyte level = (sbyte)jsonValue; // throws when jsonValue is 200 or \"5\"\n\n// after\nsbyte? level = (sbyte?)jsonValue;\nif (level is null) { /* handle missing/invalid value */ }","handlingStrategy":"type-guard","validationCode":"if (jsonValue is null || jsonValue.Type != JTokenType.Integer)\n    throw new InvalidOperationException(\"Expected an integer JSON value for SByte cast.\");\nif (jsonValue.Value<long>() is < sbyte.MinValue or > sbyte.MaxValue)\n    throw new InvalidOperationException($\"Value {jsonValue} is outside SByte range.\");","typeGuard":"static bool IsConvertibleToSByte(JsonDynamicValue v) =>\n    v?._jsonValue is { Type: JTokenType.Integer } t && t.Value<long>() is >= sbyte.MinValue and <= sbyte.MaxValue;","tryCatchPattern":"try\n{\n    sbyte n = (sbyte)jsonValue;\n}\ncatch (InvalidCastException ex)\n{\n    // log and fall back to a default or skip the record\n    sbyte n = default;\n}","preventionTips":["Use the nullable cast (sbyte?) which never throws for non-convertible values.","Range-check against -128..127 before casting to such a narrow type.","Prefer wider types (int) unless the sbyte type is truly required."],"tags":["invalid-cast","json","numeric-conversion","exception"],"backgroundTag":"type-mismatch","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}