JustArchiNET/ArchiSteamFarm · warning · NotSupportedException

classid is null!

Error message

classid is null!

What it means

While processing each CEconItem_Description in the inventory response, ASF requires description.classid to be non-zero. A zero classid means Steam sent a description without an identifying class id, which breaks description deduplication and asset matching; ASF throws a NotSupportedException ('classid is null!'). This guards data integrity rather than connectivity.

Source

Thrown at ArchiSteamFarm/Steam/Integration/ArchiHandler.cs:300

					throw new InvalidOperationException(nameof(response.Body.descriptions));
				}

				if (response.Body.total_inventory_count > Array.MaxLength) {
					throw new InvalidOperationException(nameof(response.Body.total_inventory_count));
				}

				assetIDs ??= [with((int) response.Body.total_inventory_count)];

				if (descriptions == null) {
					descriptions = new Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription>();
				} else {
					// We don't need descriptions from the previous request
					descriptions.Clear();
				}

				foreach (CEconItem_Description? description in response.Body.descriptions) {
					if (description.classid == 0) {
						throw new NotSupportedException(Strings.FormatErrorObjectIsNull(nameof(description.classid)));
					}

					(ulong ClassID, ulong InstanceID) key = (description.classid, description.instanceid);

					if (descriptions.ContainsKey(key)) {
						continue;
					}

					descriptions.Add(key, new InventoryDescription(description));
				}

				foreach (CEcon_Asset? asset in response.Body.assets.Where(asset => assetIDs.Add(asset.assetid))) {
					InventoryDescription? description = descriptions.GetValueOrDefault((asset.classid, asset.instanceid));

					// Extra bulletproofing against Steam showing us middle finger
					if ((tradableOnly && (description?.Tradable != true)) || (marketableOnly && (description?.Marketable != true))) {
						continue;
					}

View on GitHub (pinned to fe57c4129f)

Solutions

  1. Retry the inventory request; transient malformed entries usually resolve.
  2. Reduce itemsCountPerRequest to lower the chance of a truncated/partial page.
  3. Report the occurrence with the app/context if it persists, as it indicates a Steam-side data defect.
  4. Handle NotSupportedException in the caller and fall back to the HTTP inventory path (ArchiWebHandler.GetInventoryAsync).
Defensive patterns

Strategy: fallback

Validate before calling

// Lower page size to reduce malformed-description probability.
ushort pageSize = Math.Min(itemsCountPerRequest, (ushort) 2000);

Try / catch

try { await foreach (var a in handler.GetMyInventoryAsync(itemsCountPerRequest: 2000)) { /* ... */ } }
catch (NotSupportedException ex) when (ex.Message.Contains("classid")) {
    // fall back to ArchiWebHandler.GetInventoryAsync HTTP path
}

Prevention

When it happens

Trigger: Steam's inventory payload contains a description entry with classid == 0 (absent/unset), so the (ClassID, InstanceID) key would collide or be unmatchable to assets.

Common situations: Steam returns a malformed/partial description entry during GC instability; a brand-new item type Steam has not fully populated; corrupted response under heavy load.

Related errors


AI-assisted analysis of JustArchiNET/ArchiSteamFarm@fe57c4129f (2026-08-13). Data as JSON: /api/errors/20745cd11b07d7ec. Report an issue: GitHub.