{"record":{"id":"2c1f109658622c76","repo":"twentyhq/twenty","slug":"upsertrowlevelpermissionpredicates-returned-no-pre-2c1f10","errorCode":null,"errorMessage":"upsertRowLevelPermissionPredicates returned no predicate for workspaceMember","messagePattern":"upsertRowLevelPermissionPredicates returned no predicate for workspaceMember","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-apps/internal/twenty-partners/src/scripts/configure-partner-rls.ts","lineNumber":575,"sourceCode":"      input: {\n        roleId: partnerRole.id,\n        objectMetadataId: workspaceMemberId,\n        predicates: [\n          {\n            fieldMetadataId: workspaceMemberIdFieldId,\n            operand: 'IS',\n            workspaceMemberFieldMetadataId: workspaceMemberIdFieldId,\n          },\n        ],\n        predicateGroups: [],\n      } satisfies UpsertPredicatesInput,\n    });\n\n    const wmPredicate =\n      wmData.upsertRowLevelPermissionPredicates.predicates[0];\n\n    if (!wmPredicate) {\n      throw new Error(\n        'upsertRowLevelPermissionPredicates returned no predicate for workspaceMember',\n      );\n    }\n\n    results.push(wmPredicate);\n    console.log(\n      `[rls:configure] ✓ workspaceMember: predicate id=${wmPredicate.id} ` +\n        `(fieldMetadataId=${wmPredicate.fieldMetadataId}, operand=${wmPredicate.operand})`,\n    );\n  }\n\n  console.log(\n    `\\n[rls:configure] Done — ${results.length} predicates upserted on Partner role ` +\n      `(${SIMPLE_TARGET_OBJECTS.length} simple objects + opportunity OR group + workspaceMember self-scope)`,\n  );\n  console.log(`\\n${APPLY_WORKFLOW_WARNING}`);\n\n  // ── 5. Verify Opportunity field permissions (set via manifest, not here — see header) ─","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-apps/internal/twenty-partners/src/scripts/configure-partner-rls.ts#L557-L593","documentation":"Thrown by the partner RLS script after upserting a single workspaceMember predicate (`id IS the current member`) that scopes the partner role's read to its own member record. The code indexes `predicates[0]` from the mutation result; if the array is empty the predicate was not persisted, so the role would have no scoping rule and the script aborts. Like error 20, this is a provisioning-script hard stop, not user-facing runtime.","triggerScenarios":"Calling `upsertRowLevelPermissionPredicates` for the workspaceMember object with a `workspaceMemberIdFieldId` or `workspaceMemberId` (object metadata id) that does not exist in the target workspace, with RLS disabled on workspaceMember, or with a `partnerRole.id` that has already been deleted. An empty `predicates` array in the response triggers it.","commonSituations":"Running the configure script against a workspace that was reset or seeded with different universal identifiers, pointing at the wrong environment, or a stale `partnerRole` lookup earlier in the script that returned a role id the metadata layer rejects.","solutions":["Log `wmData.upsertRowLevelPermissionPredicates` in full before the index access to confirm whether `predicates` is empty versus the whole response being malformed.","Verify `workspaceMemberIdFieldId` and `workspaceMemberId` (object metadata id) resolve to the workspaceMember object/field in this workspace via a `fieldMetadata`/`objectMetadata` query.","Confirm `partnerRole.id` is still valid and that RLS is enabled on the workspaceMember object.","Re-run against a freshly reset workspace so the metadata IDs the script depends on are present."],"exampleFix":"// before\nconst wmPredicate = wmData.upsertRowLevelPermissionPredicates.predicates[0];\nif (!wmPredicate) {\n  throw new Error('upsertRowLevelPermissionPredicates returned no predicate for workspaceMember');\n}\n\n// after — guard the whole response shape, not just index 0\nconst wmPredicates = wmData?.upsertRowLevelPermissionPredicates?.predicates;\nif (!Array.isArray(wmPredicates) || wmPredicates.length === 0) {\n  throw new Error(\n    `upsertRowLevelPermissionPredicates returned no predicate for workspaceMember (roleId=${partnerRole.id}, fieldMetadataId=${workspaceMemberIdFieldId})`,\n  );\n}","handlingStrategy":"validation","validationCode":"// Before the workspaceMember upsert, confirm the field + object exist.\nconst wmField = await fetchFieldMetadataById(metadataUrl, apiKey, workspaceMemberIdFieldId);\nif (!wmField) {\n  throw new Error(`workspaceMember field ${workspaceMemberIdFieldId} not found in workspace`);\n}","typeGuard":"const hasPredicate = (\n  data: unknown,\n): data is { upsertRowLevelPermissionPredicates: { predicates: [{ id: string }] } } =>\n  typeof data === 'object' &&\n  data !== null &&\n  Array.isArray((data as any).upsertRowLevelPermissionPredicates?.predicates) &&\n  (data as any).upsertRowLevelPermissionPredicates.predicates.length > 0;","tryCatchPattern":null,"preventionTips":["Resolve workspaceMember object/field IDs from universal identifiers each run instead of trusting constants.","Validate the partnerRole.id is still present before the upsert loop.","Treat an empty predicates array as a hard configuration error and log the full mutation response.","Run against a clean, freshly seeded workspace."],"tags":["rls","metadata-mutation","partner-setup","configuration","script"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}