{"record":{"id":"c6d87e2abe548b3b","repo":"JustArchiNET/ArchiSteamFarm","slug":"required-field-field-name-expects-a-non-null-val","errorCode":null,"errorMessage":"Required field {field.Name} expects a non-null value.","messagePattern":"Required field (.+?) expects a non-null value\\.","errorType":"validation","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"ArchiSteamFarm/Helpers/Json/JsonUtilities.cs","lineNumber":184,"sourceCode":"\t\tif (string.IsNullOrEmpty(memberName) || (memberName == property.Name)) {\n\t\t\t// We don't have anything to work with further, there is no ShouldSerialize() method\n\t\t\treturn null;\n\t\t}\n\n\t\tresult = parent.GetMethod($\"ShouldSerialize{memberName}\", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null);\n\n\t\t// Use alternative method if it exists and returns a boolean\n\t\treturn result?.ReturnType == typeof(bool) ? result : null;\n\t}\n\n\t[UnconditionalSuppressMessage(\"AssemblyLoadTrimming\", \"IL2075\", Justification = \"We don't care about trimmed properties, it's not like we can make it work differently anyway\")]\n\tprivate static void OnPotentialDisallowedNullsDeserialized(object obj) {\n\t\tArgumentNullException.ThrowIfNull(obj);\n\n\t\tType type = obj.GetType();\n\n\t\tforeach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(field => field.IsDefined(typeof(JsonDisallowNullAttribute), false) && (field.GetValue(obj) == null))) {\n\t\t\tthrow new JsonException($\"Required field {field.Name} expects a non-null value.\");\n\t\t}\n\n\t\tforeach (PropertyInfo property in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(property => (property.GetMethod != null) && property.IsDefined(typeof(JsonDisallowNullAttribute), false) && (property.GetValue(obj) == null))) {\n\t\t\tthrow new JsonException($\"Required property {property.Name} expects a non-null value.\");\n\t\t}\n\t}\n\n\tprivate static bool ShouldSerialize(MethodInfo shouldSerializeMethod, object parent) {\n\t\tArgumentNullException.ThrowIfNull(shouldSerializeMethod);\n\t\tArgumentNullException.ThrowIfNull(parent);\n\n\t\tif (shouldSerializeMethod.ReturnType != typeof(bool)) {\n\t\t\tthrow new InvalidOperationException(nameof(shouldSerializeMethod));\n\t\t}\n\n\t\tobject? shouldSerialize = shouldSerializeMethod.Invoke(parent, null);\n\n\t\tif (shouldSerialize is not bool result) {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/JustArchiNET/ArchiSteamFarm/blob/fe57c4129f4ce02d452318cabc525eb49a087255/ArchiSteamFarm/Helpers/Json/JsonUtilities.cs#L166-L202","documentation":"Thrown by OnPotentialDisallowedNullsDeserialized, a System.Text.Json OnDeserialized callback wired onto every JsonTypeInfo (JsonUtilities.cs:114). After an object graph is deserialized, ASF scans all fields decorated with [JsonDisallowNullAttribute]; if any such field is still null, a JsonException is raised with the offending field name. It enforces that critical config fields (e.g. on GlobalConfig/BotConfig) can never silently deserialize to null.","triggerScenarios":"Deserializing a JSON config object (bot .json, GlobalConfig, GlobalDatabase) that omits a required field, supplies it as JSON null, or whose value fails to bind to the field's type so System.Text.Json leaves it null. The check fires only on types/members carrying JsonDisallowNullAttribute.","commonSituations":"A user hand-edits a bot config and removes a mandatory key; a field was renamed between ASF versions but the old config was kept; JSON casing/serialization options mismatch caused a property to deserialize as null; migration from an older config that lacks a newly-required field.","solutions":["Open the config file named in the bot/log and add the missing field with a valid non-null value.","If unsure of the schema, regenerate the config from ASF's default/template config or delete it so ASF recreates a valid one.","Upgrade to a matching ASF version so field names/types align with the config schema.","Validate the JSON with a parser (jsonlint) to rule out a syntax error that made the field silently null."],"exampleFix":"// before (bot JSON)\n{ \"Enabled\": true }\n// after (add the disallowed-null field the error names)\n{ \"Enabled\": true, \"SteamLogin\": \"myaccount\" }","handlingStrategy":"validation","validationCode":"// Validate config object has no null [JsonDisallowNull] members before use.\nvar json = File.ReadAllText(configPath);\nusing JsonDocument doc = JsonDocument.Parse(json);\nforeach (JsonProperty prop in doc.RootElement.EnumerateObject()) {\n    if (configuredRequiredFields.Contains(prop.Name) &&\n        prop.Value.ValueKind == JsonValueKind.Null) {\n        throw new InvalidOperationException($\"Config '{prop.Name}' is null in {configPath}\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try { MyConfig cfg = JsonSerializer.Deserialize<MyConfig>(json, ArchiSteamFarm.Options)!; }\ncatch (JsonException ex) when (ex.Message.Contains(\"expects a non-null value\")) {\n    // surface the offending field name from the message and report config issue\n    logger.LogError(ex, \"Config missing a required field\");\n}","preventionTips":["Always edit ASF config through ASF's own generation rather than hand-editing JSON.","Keep a known-good config backup to diff against when this fires.","Run the ASF build whose schema matches the config files you deploy."],"tags":["json","deserialization","configuration","validation","system-text-json"],"backgroundTag":null,"analyzedSha":"fe57c4129f4ce02d452318cabc525eb49a087255","analyzedAt":"2026-08-13T17:26:20.146Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}