microsoft/aspire · error · InvalidDataException
' ' must contain a JSON object.
Error message
'{CurrentStateProperty}' must contain a JSON object. What it means
The 'currentState' property of the migration state must be a JSON string that itself parses to a JSON object (state is stored serialized as a string). If the parsed value is null or not an object — or JsonNode.Parse fails to yield an object — InvalidDataException is thrown.
Solutions
- Repair currentState to be a JSON string containing a valid JSON object (e.g. "{}"), or remove the property if the tooling treats null as no current state.
- Delete the corrupt migration/state file and re-run so it is regenerated.
- Restore from backup if the file contained real deployment state you need.
Example fix
// before (state file)
{ "currentState": "" }
// after
{ "currentState": "{\"resources\":{}}" } Defensive patterns
Strategy: validation
Validate before calling
// currentState must be a string whose content parses to a JSON object
if (migrationState["currentState"] is JsonValue v &&
(!v.TryGetValue<string>(out var s) || JsonNode.Parse(s) is not JsonObject))
{
throw new InvalidDataException("currentState must be a JSON string containing a JSON object.");
} Type guard
static bool HasValidCurrentState(JsonObject migrationState) =>
migrationState["currentState"] is not JsonValue v
|| (v.TryGetValue<string>(out var s) && JsonNode.Parse(s) is JsonObject); Try / catch
try { await manager.LoadStateAsync(ct); }
catch (InvalidDataException ex) when (ex.Message.Contains("currentState") && ex.Message.Contains("JSON object"))
{
File.Move(statePath, statePath + ".corrupt", overwrite: true);
} Prevention
- Never write an empty string for currentState; use an escaped empty object ("{}") or omit the property.
- Serialize embedded state with JsonSerializer and store it as a string.
- Validate the file after any external tool touches it.
When it happens
Trigger: Loading a migration state file where currentState is an empty string, or a string that parses to null/array/scalar rather than an object.
Common situations: A write that serialized the current state incorrectly or truncated the embedded JSON string; manual edits that emptied the string; schema drift between Aspire versions.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- ' ' must be a JSON string.
- ' ' must be a JSON string.
- ' ' must be a JSON object.
- Cannot convert to boolean for key
- Deployment state must contain a JSON object.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/2178d66f63f5a703.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Pipelines/Internal/FileDeploymentStateManager.cs:765
{
var legacyFallbackDisabled = migrationState[LegacyFallbackDisabledProperty]?.GetValue<bool>() ?? false;
var legacyStateSnapshot = migrationState[LegacyStateProperty] switch
{
null => [],
JsonObject legacyState => legacyState,
_ => throw new InvalidDataException($"'{LegacyStateProperty}' must be a JSON object.")
};
var claimedSectionNames = migrationState[ClaimedSectionsProperty] switch
{
null => [],
JsonValue claimedSectionsValue => ParseClaimedSectionNames(claimedSectionsValue),
_ => throw new InvalidDataException($"'{ClaimedSectionsProperty}' must be a JSON string.")
};
var currentState = migrationState[CurrentStateProperty] switch
{
null => null,
JsonValue stateValue => JsonNode.Parse(stateValue.GetValue<string>())?.AsObject()
?? throw new InvalidDataException($"'{CurrentStateProperty}' must contain a JSON object."),
_ => throw new InvalidDataException($"'{CurrentStateProperty}' must be a JSON string.")
};
return new(legacyFallbackDisabled, legacyStateSnapshot, claimedSectionNames, currentState);
}
private static string[] ParseClaimedSectionNames(JsonValue claimedSectionsValue)
{
var claimedSectionNames = JsonSerializer.Deserialize<string?[]>(
claimedSectionsValue.GetValue<string>());
if (claimedSectionNames is null ||
claimedSectionNames.Any(string.IsNullOrWhiteSpace))
{
throw new InvalidDataException(
$"'{ClaimedSectionsProperty}' must contain a JSON array of non-empty strings.");
}
return [.. claimedSectionNames.Select(static sectionName => sectionName!)];View on GitHub (pinned to 25830f84bd)