Open Cloud Data Stores v2 rejects valid JSON object value with "Value cannot be null", while v1 accepts it

When using the Open Cloud Data Stores v2 API (PATCH /cloud/v2/universes/{universeId}/data-stores/{dataStoreId}/entries/{entryId}), sending a valid JSON object in the value field returns a 400 Bad Request with the error:

{"code": 3, "message": "Value cannot be null. (Parameter 'value')"}

However, the exact same data serialized as a JSON string and sent through the legacy Data Stores v1 API (POST /datastores/v1/...) succeeds and is correctly loaded in-game as a Luau table.

This makes it impossible to safely edit Data Store entries that are consumed as tables by Luau code (e.g., data managed by ProfileStore) via the recommended v2 API.

Reproduction Steps

  1. Read an existing Data Store entry via v2:
GET https://apis.roblox.com/cloud/v2/universes/{universeId}/data-stores/PlayerData/entries/{userId}
x-api-key: {key}
  1. Modify the value object (e.g., change Data.Currencies.Coins).

  2. Send it back via v2:

PATCH https://apis.roblox.com/cloud/v2/universes/{universeId}/data-stores/PlayerData/entries/{userId}
x-api-key: {key}
If-Match: {etag}
Content-Type: application/json
{"value": {"Data": {...}, "MetaData": {...}, "GlobalUpdates": [...], "UserIds": [...]}}
  1. Observe the 400 error:
{"code": 3, "message": "Value cannot be null. (Parameter 'value')"}
  1. Serialize the same object as a JSON string and send via v1:

POST https://apis.roblox.com/datastores/v1/universes/{universeId}/standard-datastores/datastore/entries/entry?datastoreName=PlayerData&entryKey={userId}
x-api-key: {key}
content-md5: {md5}
Content-Type: application/json
{"Data": {...}, "MetaData": {...}, "GlobalUpdates": [...], "UserIds": [...]}
  1. The v1 request succeeds, and the value is loaded in-game as a table.

Expected behavior

The v2 API should accept a JSON object in the value field and store it so that it can be read back in-game as a Luau table, just like the v1 API does.

Alternatively, if the v2 API intentionally requires a different format (e.g., string-encoded JSON), the documentation and error message should clearly indicate that.

Actual Behavior

  • v2 with value as object: 400 Bad Request, “Value cannot be null. (Parameter ‘value’)”
  • v2 with value as JSON string: API accepts, but the value is stored as a raw string, which breaks Luau code expecting a table.
  • v1 with body as JSON string: API accepts and stores the value correctly as a table in-game.

This bug makes the recommended v2 API unusable for editing Data Store entries that are consumed as structured tables by Luau scripts. In my case, this breaks compatibility with ProfileStore, which expects the Data Store entry to be a table with a specific structure (Data, MetaData, GlobalUpdates, UserIds, etc.). When the v2 API stores the value as a string, ProfileStore detects it as invalid data and emits:

[ProfileStore]: Invalid profile was overwritten
1 Like

Happened to me recently. This bug is preventing us from using the V2 Data Stores API, despite our payloads being valid JSON and fully compatible with V1. We hope this gets fixed soon, as it’s currently blocking production use of V2.