Skip to content

Troubleshooting

Start with the symptom you can see. Keep Studio’s Output window open; Scribe’s log code usually points to the next step.

SymptomFirst check
My script cannot find Scribe or the data moduleCompare the names and locations with the Getting Started file tree.
Every test starts with fresh dataCheck Mode and the real-saving checklist. Mock data is not kept between server runs.
Server data changes but my UI does notRequire the shared module from a LocalScript and use Observe; see client syncing.
A value changes on the client, then changes backClient writes are local. Use a server command for a lasting change.
A write changes the value differently than I expectedCheck the field’s bounds and clamping rules.
An offline edit or erase is refusedCheck whether the player is online, then read the returned reason; see offline operations.
Scribe reports an outage or repeated save errorsInspect diagnostics and the specific log code.
  1. Require the shared data module from a server Script at startup.
  2. Call Data.WaitForData(player) before reading the player’s fields.
  3. Handle both results. If the data is nil, inspect the reason instead of indexing into it.
local data, reason = Data.WaitForData(player)
if not data then
warn("Could not load data:", reason)
return
end
print(data.Coins.Get())

This example assumes Data is your shared module’s .Server and player is the joining Player. Getting Started has the complete script. The session lifecycle guide explains each failure reason, including a player leaving during loading and an erase preventing a join.

  • Mode = "Mock" starts fresh on the next server run. This is expected.
  • Mode = "NoSave" reads a real profile but never saves changes.
  • For Mode = "Live", use a separate test experience and enable Studio access to API services. If Output says [ProfileStore]: Roblox API services unavailable - data will not be saved, the store has fallen back to memory.
  • Check whether a wipe guard, migration error, or store failure is logged. Do not bypass a guard just to silence the warning.

Follow the save-and-reload checklist to verify persistence. After a manual save, inspect Flush’s result: false is not permission to repeat a purchase or reward. See saving.

The shared module must be required on both the server and client. The client require starts the connection to the server. A CLIENT_HANDSHAKE_TIMEOUT log can indicate that this step is missing.

Use Observe for UI: it runs immediately with the current value and again when synced data arrives. An initial template default is normal. For a one-time read that needs loaded data, check the boolean returned by Data.WaitForData() on the client before continuing.

Also check visibility rules. A server-only field is deliberately unavailable to the client.

Treat tables returned by Get() as read-only. A returned table can be the stored table itself; editing it directly bypasses Scribe’s validation, change events, and replication. Some values are rebuilt as copies, so direct edits to those do not update the profile at all. Use the field methods to write, or Clone() to make a separate copy. See reading and writing values.

An example uses a field my template does not have

Section titled “An example uses a field my template does not have”

The first tutorial uses a small GameData module. Feature guides use the larger Emberfall example. Add the fields that the feature needs, or adapt the example’s paths to your template. Do not run two independent data modules against the same player profile key.

Include the Scribe version, the exact log code or returned reason, a minimal template and script that reproduce the problem, and whether it happens in Mock or Live mode. Remove private player data and credentials. Diagnostics explains how to inspect recent logs and save state.