microsoft/aspire · error · InvalidDataException

Deployment state must contain a JSON object.

Error message

Deployment state must contain a JSON object.

What it means

ParseStateFile parses the deployment state file and throws InvalidDataException if JsonNode.Parse does not yield a JsonObject, i.e. the file contains a JSON array, string, number, or invalid/truncated JSON rather than the expected top-level object. Parsing tolerates comments and trailing commas but the root must be an object.

Solutions

  1. Open the state file and fix the root to be a JSON object ({...}); remove arrays or bare values at the top level.
  2. If the file is truncated or corrupt, delete it and re-run the deployment so state is regenerated.
  3. Restore the file from backup or source control if it was hand-edited.

Example fix

// before (state file)
[ { "a": 1 } ]
// after
{ "a": 1 }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the state file before use
using var doc = JsonNode.Parse(File.ReadAllText(statePath),
    documentOptions: new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true });
if (doc is not JsonObject)
{
    throw new InvalidDataException($"{statePath} must contain a top-level JSON object.");
}

Type guard

static bool IsValidStateFile(string content) =>
    JsonNode.Parse(content) is JsonObject;

Try / catch

try { var state = await manager.LoadStateFileAsync(path, ct); }
catch (InvalidDataException ex) when (ex.Message.Contains("must contain a JSON object"))
{
    // quarantine the corrupt file and start fresh
    File.Move(path, path + ".corrupt", overwrite: true);
}

Prevention

When it happens

Trigger: Calling LoadStateFileAsync/LoadStateFile when the deployment state file was hand-edited to an array or scalar, truncated by a crashed writer, or is empty/corrupt on disk.

Common situations: Manual edits of ~/.aspire/deployment state files; a previous run was killed mid-write; file synced/truncated by tooling; user pasted a JSON array of key/value pairs instead of an object.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/4b4ca6b4a8db0fa6. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/Pipelines/Internal/DeploymentStateManagerBase.cs:138

        return ParseStateFile(fileContent);
    }

    private static JsonObject ParseStateFile(string? fileContent)
    {
        if (fileContent is null)
        {
            return [];
        }

        var jsonDocumentOptions = new JsonDocumentOptions
        {
            CommentHandling = JsonCommentHandling.Skip,
            AllowTrailingCommas = true,
        };

        if (JsonNode.Parse(fileContent, documentOptions: jsonDocumentOptions) is not JsonObject flattenedState)
        {
            throw new InvalidDataException("Deployment state must contain a JSON object.");
        }

        return JsonFlattener.UnflattenJsonObject(flattenedState);
    }

    /// <inheritdoc/>
    public async Task SaveStateAsync(JsonObject state, CancellationToken cancellationToken = default)
    {
        await _stateLock.WaitAsync(cancellationToken).ConfigureAwait(false);
        try
        {
            await SaveStateToStorageAsync(state, sectionName: null, originalSectionData: null, cancellationToken).ConfigureAwait(false);
        }
        finally
        {
            _stateLock.Release();
        }
    }

View on GitHub (pinned to 25830f84bd)