Skip to content

Protected Fields

Protected fields are component fields that are silently excluded from update operations by default. When you send an update request that includes a protected field, the request succeeds but the protected field's value remains unchanged — no error is returned.

This behaviour catches many users off-guard: the API responds with 200 OK yet the field keeps its old value.


Force Updating Protected Fields

To update a user-defined protected field, pass force_update_protected_fields: true in the request options.

Warning

Force-updating protected fields bypasses the safety net intentionally put in place. Use it only when you explicitly need to modify a field that was marked as protected.

Supported Endpoints

Endpoint Method Option location
/v4/system/component/{ref}/model/{uuid} POST options.force_update_protected_fields
/v4/system/component/{ref}/modify/model PATCH options.force_update_protected_fields
/v4/system/component/{ref}/models/bulk PATCH options.force_update_protected_fields

Examples

Single Update

import { Component } from "@ptkl/sdk"

const accounts = new Component("finance::account")

// ❌ This will NOT update account_number (it's protected)
await accounts.update(uuid, {
    account_number: "NEW-123",
    name: "Updated Name",
})

// ✅ This WILL update account_number
await accounts.update(uuid, {
    account_number: "NEW-123",
    name: "Updated Name",
}, {
    force_update_protected_fields: true,
})
# ❌ Protected field is silently ignored
curl -X POST /v4/system/component/finance::account/model/{uuid} \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "account_number": "NEW-123",
      "name": "Updated Name"
    }
  }'

# ✅ Force update includes the protected field
curl -X POST /v4/system/component/finance::account/model/{uuid} \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "account_number": "NEW-123",
      "name": "Updated Name"
    },
    "options": {
      "force_update_protected_fields": true
    }
  }'

Concurrent Update

import { Component } from "@ptkl/sdk"

const accounts = new Component("finance::account")

await accounts.concurrentUpdate(uuid, model.__version__, {
    account_number: "NEW-456",
}, {
    force_update_protected_fields: true,
})
curl -X POST /v4/system/component/finance::account/model/{uuid} \
  -H "Content-Type: application/json" \
  -d '{
    "version": 3,
    "data": {
      "account_number": "NEW-456"
    },
    "options": {
      "force_update_protected_fields": true
    }
  }'

Modify (Filter-Based Update)

import { Component } from "@ptkl/sdk"

const accounts = new Component("finance::account")

await accounts.modify(
    { status: "migrating" },
    { account_number: "MIGRATED-001" },
    { upsert: false, force_update_protected_fields: true }
)
curl -X PATCH /v4/system/component/finance::account/modify/model \
  -H "Content-Type: application/json" \
  -d '{
    "filters": { "status": "migrating" },
    "data": {
      "account_number": "MIGRATED-001"
    },
    "options": {
      "upsert": false,
      "force_update_protected_fields": true
    }
  }'

Bulk Update

import { Component } from "@ptkl/sdk"

const accounts = new Component("finance::account")

await accounts.updateMany([
    { uuid: "aaa-111", account_number: "ACC-001" },
    { uuid: "bbb-222", account_number: "ACC-002" },
], {
    force_update_protected_fields: true,
    rollbackOnError: true,
})
curl -X PATCH /v4/system/component/finance::account/models/bulk \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
      { "uuid": "aaa-111", "account_number": "ACC-001" },
      { "uuid": "bbb-222", "account_number": "ACC-002" }
    ],
    "options": {
      "force_update_protected_fields": true,
      "rollback_on_error": true
    }
  }'

Common Pitfalls

Symptom Cause Fix
Update returns 200 OK but field didn't change The field is marked as protected Pass force_update_protected_fields: true in options
Field still won't update even with force flag The field is a system-level protected field (e.g. uuid, created_at) System fields are managed by the platform and cannot be overridden
Workflow Before::Update doesn't see the field Protected fields are stripped before the workflow fires Use the force flag so the field reaches the workflow

When to Use Protected Fields

Protected fields are ideal for:

  • Immutable identifiers — account numbers, external IDs that should not change after creation
  • Computed fields — values set by workflows or functions that users should not overwrite directly
  • Audit fields — fields that should only be modified through controlled processes

Use force_update_protected_fields when you need to perform administrative corrections, data migrations, or controlled updates from trusted code paths (e.g. server-side SDK calls, admin workflows).