Reference
Rule reference
Guardian currently runs 26 rules. Each rule is versioned: when a rule changes, its version changes, so you can tell whether a new finding comes from your code or from the rule.
Monetization · 7
Developer products are sold but no purchase handler is set
monetization.process-receipt.missing@1The game prompts developer product purchases but no enabled server script assigns MarketplaceService.ProcessReceipt.
ProcessReceipt is assigned more than once
monetization.process-receipt.multiple@1Only one ProcessReceipt callback can be active; later assignments replace earlier ones.
ProcessReceipt is assigned on the client
monetization.process-receipt.client@1ProcessReceipt only works on the server. A client assignment never runs.
Purchase handler never returns PurchaseGranted
monetization.process-receipt.never-granted@1A ProcessReceipt handler that never returns PurchaseGranted leaves every purchase unfinished.
Purchase handler cannot ask Roblox to retry
monetization.process-receipt.no-retry-path@1The handler never returns NotProcessedYet, so failures are reported to Roblox as success.
Purchase handler does not track PurchaseId
monetization.process-receipt.not-idempotent@1Roblox can deliver the same receipt more than once. Handlers should record PurchaseId.
Game pass ownership is only checked on the client
monetization.game-pass.client-only-check@1Perks granted from client-side ownership checks can be unlocked by exploiters.
Security · 8
Module loaded from the Roblox website by asset id
security.require-by-asset-id@1require(assetId) downloads code that is not in your place and can change at any time.
Code is compiled at runtime with loadstring
security.loadstring@1loadstring runs arbitrary text as code and is a common backdoor and exploit vector.
Credential stored in a script
security.hardcoded-secret@1Secrets in source travel with every copy of the place file.
Server applies a value sent by the client
security.remote-trusts-client-value@1Remote handlers must not write client-supplied amounts into player state.
Script appears to be obfuscated
security.obfuscated-source@1Obfuscated code cannot be reviewed and is a strong indicator of a backdoor.
Function environments are read or replaced
security.function-environment@1getfenv and setfenv are rarely needed and are frequently used to hide malicious code.
Remote can spam DataStore requests
security.remote-triggers-datastore@1A client can fire this remote as often as it likes, and each call makes a DataStore request.
Server waits on InvokeClient
security.server-invokes-client@1InvokeClient yields until the client answers, and the client controls the answer.
Reliability · 4
DataStore requests are not wrapped in pcall
reliability.datastore-without-pcall@1DataStore calls are network requests that can fail and throw.
Player data may be lost when a server shuts down
reliability.no-bind-to-close@1Games that save to DataStores should save remaining players in game:BindToClose.
Player data saved with SetAsync
reliability.datastore-setasync-player-data@1SetAsync overwrites whatever is stored. UpdateAsync lets the save check the stored value first.
Player data has no session lock
reliability.no-session-locking@1Loads on join and saves on leave with no lock, so two servers can hold the same player at once.
Performance · 5
Infinite loop never yields
performance.loop-without-yield@1`while true do` without a wait freezes the script, and on the client the whole game.
DataStore called every frame or on touch
performance.datastore-per-frame@1DataStore requests inside Heartbeat, Stepped or Touched handlers hit the request limit.
Connection made per player is never disconnected
performance.connection-leak-per-player@1Connecting to a global signal each time a player or character spawns leaks a connection every time.
Per-player table is never cleared
performance.player-table-not-cleared@1Entries keyed by player are added but never set to nil when the player leaves.
Remote fired every frame
performance.remote-fired-every-frame@1Firing a RemoteEvent from Heartbeat or a tight loop sends a packet per frame per player.
Quality · 2
Client script changes leaderstats
quality.client-writes-leaderstats@1Changes made by LocalScripts do not replicate to the server.
Deprecated wait, spawn or delay
quality.deprecated-scheduler-globals@1The legacy scheduling globals are throttled; the task library replaces them.