LykosAI/StabilityMatrix · error · InvalidDataException
JSON does not start with '{'.
Error message
JSON does not start with '{'. What it means
ParseAsync throws this when byte 8 of the safetensors file (the first byte of the JSON header) is not '{'. The 8-byte length prefix must be immediately followed by the opening brace of the JSON header.
Solutions
- Verify the file is a genuine safetensors file (magic: 8-byte little-endian length then '{').
- Reset the stream position to 0 before calling ParseAsync.
- Re-download or re-convert the model file.
- Add a pre-check that reads the first 9 bytes and validates the pattern.
Example fix
// before
var meta = await SafetensorMetadata.ParseAsync(fileStream);
// after
fileStream.Position = 0;
var probe = new byte[9];
await fileStream.ReadExactlyAsync(probe);
if (probe[8] != (byte)'{') throw new InvalidDataException("Not a safetensors file.");
fileStream.Position = 0;
var meta = await SafetensorMetadata.ParseAsync(fileStream); Defensive patterns
Strategy: validation
Validate before calling
using var fs = File.OpenRead(path);
var probe = new byte[9];
if (await fs.ReadAsync(probe) < 9 || probe[8] != (byte)'{')
throw new InvalidDataException("File does not look like safetensors.");
fs.Position = 0; Type guard
bool LooksLikeSafetensors(byte[] first9) => first9.Length >= 9 && first9[8] == (byte)'{'; Try / catch
try { var meta = await SafetensorMetadata.ParseAsync(stream); }
catch (InvalidDataException ex)
{
_logger.LogError(ex, "Not a valid safetensors file");
notificationService.ShowPersistentDialog("Invalid file", ex.Message);
} Prevention
- Validate file magic/header before parsing
- Re-download files that fail validation instead of retrying parses
- Ensure the stream was not already partially consumed
- Check downloads complete before hashing/parsing
When it happens
Trigger: Reading a file whose byte at offset 8 is not '{': non-safetensors files, wrong stream position, headers whose length prefix is misinterpreted.
Common situations: Renamed model files (ckpt/gguf named .safetensors), partially written files, reading from a stream that was already partially consumed.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- API key is required
- Archive must be a zipped tar.
- CurrentBitmapSize is null
- Definition: ' ' has options, it must have exactly 1 option…
- Definition ' ' has InitialValue of ' ', but it was not…
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/6ccabdec32c887e5.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Core/Models/SafetensorMetadata.cs:48
/// <param name="safetensorStream">Stream to the SafeTensor file.</param>
/// <returns>The parsed metadata. Can be <see langword="null"/> if the file does not contain metadata.</returns>
public static async Task<SafetensorMetadata?> ParseAsync(Stream safetensorStream)
{
// 8 bytes unsigned little-endian 64-bit integer
// 1 byte start of JSON object '{'
Memory<byte> buffer = new byte[9];
await safetensorStream.ReadExactlyAsync(buffer).ConfigureAwait(false);
var span = buffer.Span;
const ulong MAX_ALLOWED_JSON_LENGTH = 100 * 1024 * 1024; // 100 MB
var jsonLength = BinaryPrimitives.ReadUInt64LittleEndian(span);
if (jsonLength > MAX_ALLOWED_JSON_LENGTH)
{
throw new InvalidDataException("JSON length exceeds the maximum allowed size.");
}
if (span[8] != '{')
{
throw new InvalidDataException("JSON does not start with '{'.");
}
// Unfornately Utf8JsonReader does not support reading from a stream directly.
// Usually the size of the entire JSON object is less than 500KB,
// using a pooled buffer should reduce the number of large allocations.
var jsonBytes = ArrayPool<byte>.Shared.Rent((int)jsonLength);
try
{
// Important: the length of the rented buffer can be larger than jsonLength
// and there can be additional junk data at the end.
// we already read {, so start from index 1
jsonBytes[0] = (byte)'{';
await safetensorStream
.ReadExactlyAsync(jsonBytes, 1, (int)(jsonLength - 1))
.ConfigureAwait(false);
// read the JSON with Utf8JsonReader, then only deserialize what we needView on GitHub (pinned to af93d6ef57)