microsoft/aspire · error · InvalidDataException
' ' must be a JSON string.
Error message
'{ClaimedSectionsProperty}' must be a JSON string. What it means
The migration state record requires the 'claimedSections' property to be either absent/null or a JSON value parseable as an array of section-name strings; any other JSON type throws InvalidDataException. It tracks which sections have been claimed during the state-file migration.
Solutions
- Set claimedSections to the expected string form (e.g. a JSON string or array of strings naming claimed sections) or remove the property.
- Delete the corrupt migration state file and re-run the deployment to regenerate it.
- Avoid manual edits; let the pipeline own this file.
Example fix
// before (state file)
{ "claimedSections": { "sectionA": true } }
// after
{ "claimedSections": ["sectionA"] } Defensive patterns
Strategy: validation
Validate before calling
// Validate before handing the file to the manager
if (migrationState["claimedSections"] is not (null or JsonValue))
{
throw new InvalidDataException("claimedSections must be a JSON string (or absent).");
} Type guard
static bool HasValidClaimedSections(JsonObject migrationState) =>
migrationState["claimedSections"] is null or JsonValue; Try / catch
try { await manager.LoadStateAsync(ct); }
catch (InvalidDataException ex) when (ex.Message.Contains("claimedSections") && ex.Message.Contains("JSON string"))
{
File.Move(statePath, statePath + ".corrupt", overwrite: true);
// proceed as if no sections were claimed
} Prevention
- Treat the migration state file as tool-owned; avoid manual edits.
- Round-trip edits through System.Text.Json to preserve property types.
- Keep state files from being rewritten by external scripts.
When it happens
Trigger: Loading a migration/state file where claimedSections is an object, number, boolean, or array of non-strings instead of a JSON string/value parseable to string names.
Common situations: Hand edits to the state file; corruption from a crashed write; mixing state files produced by different Aspire versions with different schemas.
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 contain a JSON object.
- ' ' 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/f3b0db9b073f3d83.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Pipelines/Internal/FileDeploymentStateManager.cs:759
return File.Exists(migrationStatePath)
? ParseMigrationState(LoadStateFile(migrationStatePath))
: new(false, [], [], null);
}
private static MigrationState ParseMigrationState(JsonObject migrationState)
{
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))View on GitHub (pinned to 25830f84bd)