Version: 2.0.0
Category: Troubleshooting
Status: Stable
Last Updated: March 26, 2026
This guide helps troubleshoot issues with permissions and permission bit manipulation. Permission values are 25-bit flags (bits 0-24) combined using bitwise OR. The maximum value (PermAll) is 33554431.
Bit 24 (PermGuildUGCUpdate, value 16777216) was added in v0.16.0 for guild-moderated UGC (name/pfp) updates on player, planet, and substation objects. See knowledge/mechanics/ugc-moderation.md.
The permission system uses HasAll semantics: all required bits must be present in the permission value. A check like (value & required) == required must match every bit — a single matching bit is not sufficient.
The old single Hash permission has been replaced by four granular hash permissions:
| Permission | Bit | Value | Description |
|---|---|---|---|
| PermHashBuild | 20 | 1048576 | Hash permission for building |
| PermHashMine | 21 | 2097152 | Hash permission for mining |
| PermHashRefine | 22 | 4194304 | Hash permission for refining |
| PermHashRaid | 23 | 8388608 | Hash permission for raiding |
| PermHashAll | 20-23 | 15728640 | All hash permissions combined |
Symptom: Permission check fails even though permission should be granted
Cause: Required hash permission bits not included in permission value. With the split hash permissions, you may have some hash bits but not the specific one required for the operation.
Diagnosis:
GET /structs/permission/{permissionId}permission.value (numeric string)(value & 2097152) == 2097152Solution:
newValue = oldValue | 15728640(newValue & 15728640) == 15728640Example:
{
"permissionId": "0-1@1-11",
"oldValue": "1048575",
"newValue": "16777215",
"calculation": "1048575 | 15728640 = 16777215",
"hashAllCheck": "(16777215 & 15728640) == 15728640 ✓",
"hashMineCheck": "(16777215 & 2097152) == 2097152 ✓"
}
To grant PermAll (every bit including the new PermGuildUGCUpdate bit 24), use 33554431 instead of 16777215.
Reference: schemas/game-state.md#/definitions/Permission, api/queries/permission.md
Symptom: Permission value doesn’t match expected combination
Cause: Incorrect bitwise OR operation or using old 8-bit values
Diagnosis:
GET /structs/permission/{permissionId}permission.value33554431 — PermAll (all 25-bit permissions)16777216 — PermGuildUGCUpdate only (guild moderation flag, bit 24)16777215 — Pre-v0.16.0 PermAll (all 24 lower bits without PermGuildUGCUpdate)15728640 — PermHashAll only (all four hash bits)1048576 — PermHashBuild only2097152 — PermHashMine only4194304 — PermHashRefine only8388608 — PermHashRaid onlySolution:
value = permission1 | permission2(value & required) == requiredReference: schemas/game-state.md#/definitions/Permission, schemas/entities.md#/definitions/Permission
Symptom: Permission query returns permission for different object
Cause: Incorrect permission ID format or object ID
Diagnosis:
{objectId}@{playerId}type-index (e.g., 0-1 for guild, 2-1 for planet)1-{index}permission.objectId matches expected objectSolution:
{objectId}@{playerId}GET /structs/permission/object/{objectId}GET /structs/permission/player/{playerId}Reference: api/queries/permission.md, schemas/formats.md
Symptom: Permission check passes when it should fail, or fails when it should pass
Cause: Using old HasOneOf check ((value & required) != 0) instead of new HasAll check ((value & required) == required)
Diagnosis:
(value & required) != 0 — passes if any required bit is set(value & required) == required — passes only if all required bits are setExample:
{
"value": 1048576,
"required": 15728640,
"hasOneOf_WRONG": "(1048576 & 15728640) != 0 → true (only PermHashBuild set)",
"hasAll_CORRECT": "(1048576 & 15728640) == 15728640 → false (missing Mine, Refine, Raid)"
}
Solution:
!= 0 permission checks with == required checksReference: schemas/game-state.md#/definitions/Permission
Symptom: Database query for hash permission returns no results
Cause: Hash permission levels not set or query references old schema
Diagnosis:
structs.permission tableview.permissionSolution:
& 2097152 for mine)Reference: schemas/database-schema.md, api/queries/permission.md
Symptom: Transaction signing fails with permission error
Cause: Specific hash permission not granted for the operation type
Diagnosis:
(value & 1048576) == 1048576(value & 2097152) == 2097152(value & 4194304) == 4194304(value & 8388608) == 8388608Solution:
Reference: schemas/database-schema.md#/tables/signer_tx, schemas/entities.md#/definitions/Permission
Symptom: Combining permissions produces wrong value
Cause: Incorrect bitwise operation, using old values, or value overflow
Diagnosis:
value1 | value2Solution:
value = value1 | value2(value & required) == requiredvalue = value & ~bitsExample:
{
"permission1": 1048575,
"permission2": 15728640,
"combined": "1048575 | 15728640 = 16777215",
"checkHashAll": "(16777215 & 15728640) == 15728640 ✓",
"removeHashAll": "16777215 & ~15728640 = 1048575"
}
Reference: schemas/game-state.md#/definitions/Permission
Symptom: Player cannot perform action despite having object-level permission
Cause: Guild rank permissions override or supplement object-level permissions. The permission check flow is: address → ownership → object permission → guild rank permission. A missing guild rank permission can block an action even if the object permission is set.
Diagnosis:
Solution:
permission-guild-rank-set to grant the required permissions at the guild rank levelCLI Example:
# Set guild rank permissions (grant PermAll to rank)
structsd tx structs permission-guild-rank-set \
--from keyname --gas auto -y -- 0-1 1 33554431
# Revoke guild rank permissions
structsd tx structs permission-guild-rank-revoke \
--from keyname --gas auto -y -- 0-1 1
Reference: schemas/actions.md, api/queries/permission.md
| Bits | Name | Value | Description |
|---|---|---|---|
| 0-19 | Standard permissions | 1 - 524288 | Various gameplay permissions |
| 20 | PermHashBuild | 1048576 | Hash permission for building |
| 21 | PermHashMine | 2097152 | Hash permission for mining |
| 22 | PermHashRefine | 4194304 | Hash permission for refining |
| 23 | PermHashRaid | 8388608 | Hash permission for raiding |
| 24 | PermGuildUGCUpdate | 16777216 | Guild moderation of name/pfp on player, planet, substation |
GET /structs/permission/{permissionId}value = parseInt(permission.value)(value & 15728640) == 15728640GET /structs/permission/{permissionId}value = parseInt(permission.value)(value & 2097152) == 2097152newValue = currentValue | 15728640(newValue & 15728640) == 15728640newValue = currentValue & ~15728640(newValue & 15728640) == 0INVALID_MESSAGE - Invalid permission formatGENERAL_ERROR - General error (retryable)See: schemas/errors.md for complete error definitions
Always check permissions with (value & required) == required. Do not use != 0 which only verifies any single bit.
Grant only the hash permissions needed. Use PermHashBuild for builders, PermHashMine for miners, etc. Use PermHashAll only when all hash operations are needed.
After setting permissions, always verify the value matches expected combination.
Permissions are resolved in order: address → ownership → object → guild rank. A failure at any step blocks the action. Check all levels when troubleshooting.
Verify permission applies to correct object and player.
When querying database, account for granular hash permission columns.
Test permission combinations before applying to production.
../schemas/game-state.md#/definitions/Permission - Permission entity schema../api/queries/permission.md - Permission query endpoints../schemas/database-schema.md - Permission database changes../reference/entity-index.md - Permission entity information../schemas/formats.md - ID format specificationsLast Updated: March 26, 2026