platform-custom-setting-generate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Salesforce Custom Setting Generator and Validator

Salesforce Custom Setting 生成器与验证器

When to Use This Skill

何时使用此技能

Use this skill when you need to:
  • Create a Hierarchy or List custom setting
  • Generate custom setting metadata XML
  • Add or validate fields on an existing custom setting
  • Populate custom setting values (these are data, not metadata — see Section 6)
  • Troubleshoot custom setting deployment errors
A trigger bypass / kill switch is a Custom Setting — not Apex and not a
__mdt
.
When the user wants a switch admins can flip to turn behavior on or off — "disable my Account triggers during a data load", a feature toggle, a maintenance-mode flag — generate only a hierarchy custom setting with a
Checkbox
field (e.g.
Disable_Triggers__c
/
Bypass__c
). Do not author the Apex trigger, handler, or test that reads it, and do not model it as a Custom Metadata Type: the per-profile/per-user override a bypass flag needs is exactly what a hierarchy custom setting gives you and a
__mdt
does not. The Apex that checks the flag is the developer's to write — this skill generates the setting only.

当你需要以下操作时,使用此技能:
  • 创建层级或列表类型的Custom Setting
  • 生成Custom Setting元数据XML
  • 在现有Custom Setting中添加或验证字段
  • 填充Custom Setting (这些是数据而非元数据——详见第6节)
  • 排查Custom Setting部署错误
触发器绕过/终止开关是一种Custom Setting——而非Apex或
__mdt
类型。
当用户需要一个管理员可切换的开关来启用或禁用行为(例如“在数据加载期间禁用我的Account触发器”)、功能切换、维护模式标志时——仅生成带有
Checkbox
字段的层级Custom Setting(例如
Disable_Triggers__c
/
Bypass__c
)。请勿编写读取该设置的Apex触发器、处理程序或测试,也不要将其建模为Custom Metadata Type:绕过标志所需的每个配置文件/每个用户覆盖功能,正是层级Custom Setting具备而
__mdt
不具备的特性。检查该标志的Apex代码由开发者自行编写——此技能仅生成设置本身。

1. Overview and Purpose

1. 概述与用途

This document defines the mandatory constraints for generating Custom Setting metadata. A custom setting is a
CustomObject
with
<customSettingsType>
set — it is not a distinct metadata type.
File extension:
.object-meta.xml
File path:
force-app/main/default/objects/<Name>__c/<Name>__c.object-meta.xml
API name suffix:
__c
(identical to a regular custom object — the suffix does not distinguish them)
Values are data, not metadata. You can generate the setting's definition as XML, but you cannot deploy its values that way. There is no source-format equivalent of
customMetadata/
for custom settings. Never generate a file that claims to carry setting values — see Section 6 for what to do instead.

本文档定义了生成Custom Setting元数据的强制约束。Custom Setting是设置了
<customSettingsType>
CustomObject
——它并非独立的元数据类型。
文件扩展名:
.object-meta.xml
文件路径:
force-app/main/default/objects/<Name>__c/<Name>__c.object-meta.xml
API名称后缀:
__c
(与常规自定义对象相同——后缀无法区分二者)
值是数据,而非元数据。 你可以生成设置的定义XML,但无法通过这种方式部署其。Custom Setting没有类似
customMetadata/
的源格式文件夹。切勿生成声称携带设置值的文件——替代方案详见第6节

2. Syntactic Essentials (Tier 1)

2. 语法要点(一级要求)

<customSettingsType>
is mandatory — CRITICAL

<customSettingsType>
为必填项——至关重要

This is the single highest-severity rule in this skill. Omitting
<customSettingsType>
does not produce a "you forgot customSettingsType" error. The component silently stops being a custom setting and is validated as a plain custom object.
The failure is dangerous because it is recoverable in the wrong direction: an agent that omits the element, then obediently fixes each error the platform reports, ends up with a green deploy and completely the wrong kind of component.
What you seeWhat it means
Must specify a non-empty plural label for the CustomObject
You are NOT building a custom setting.
customSettingsType
is missing. Add it — do not add
pluralLabel
.
Cannot specify: nameField for CustomSettings
You ARE building a custom setting. Remove the named element.
These two strings are mutually exclusive tells. The giveaway in the first is the phrase
for the CustomObject
and the absence of any mention of custom settings.
If a deploy reports
Must specify a non-empty plural label for the CustomObject
on something the user asked to be a custom setting, never satisfy that error by adding
<pluralLabel>
.
Adding it (plus
nameField
,
deploymentStatus
, and
sharingModel
) makes the deploy succeed and creates a regular custom object that the user did not ask for.
这是此技能中最高优先级的规则。 省略
<customSettingsType>
不会产生“你忘记添加customSettingsType”的错误。组件会静默地不再是Custom Setting,而是被当作普通自定义对象进行验证。
这种失败很危险,因为它会向错误方向恢复:如果代理省略了该元素,然后按照平台报告的每个错误进行修复,最终会得到一个部署成功但完全错误的组件
错误信息含义
Must specify a non-empty plural label for the CustomObject
构建Custom Setting。缺少
customSettingsType
。添加该元素——不要添加
pluralLabel
Cannot specify: nameField for CustomSettings
正在构建Custom Setting。移除指定元素。
这两个字符串是互斥的提示。第一个错误的关键在于短语**
for the CustomObject
**且未提及任何Custom Setting相关内容。
如果部署报告
Must specify a non-empty plural label for the CustomObject
,而用户要求的是Custom Setting,绝不要通过添加
<pluralLabel>
来解决该错误。
添加该元素(加上
nameField
deploymentStatus
sharingModel
)会使部署成功,但会创建一个用户未要求的常规自定义对象。

Required and Allowed Elements

必填与允许的元素

ElementRequirementNotes
<customSettingsType>
Required
Hierarchy
or
List
— see Section 3
<label>
RequiredSingular UI name
<visibility>
Always include
Public
, or
Protected
only in a dev/sandbox/scratch org (Section 5)
<description>
Always includeExplain what the setting controls and who edits it
<enableFeeds>
OptionalAccepted
<listViews>
OptionalAccepted — permitted despite
recordTypes
and
compactLayouts
being forbidden
元素要求说明
<customSettingsType>
必填
Hierarchy
List
——详见第3节
<label>
必填单数UI名称
<visibility>
必须包含
Public
,或仅在开发/沙盒/临时组织中使用
Protected
(第5节)
<description>
必须包含说明该设置控制的内容以及编辑者
<enableFeeds>
可选允许使用
<listViews>
可选允许使用——尽管
recordTypes
compactLayouts
被禁止

Forbidden Elements

禁止的元素

Every element below produces
Cannot specify: <element> for CustomSettings
:
Forbidden elementNote
<pluralLabel>
Required on a regular custom object, forbidden here. Exactly inverted.
<nameField>
The
Name
field exists implicitly on List settings
<deploymentStatus>
<sharingModel>
Custom settings are not shared records
<enableActivities>
<enableReports>
<enableHistory>
<enableSearch>
<validationRules>
Enforce these in Apex instead
<recordTypes>
<compactLayouts>
INCORRECT — carries a regular custom object's required elements:
xml
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
  <customSettingsType>Hierarchy</customSettingsType>
  <label>Feature Flags</label>
  <pluralLabel>Feature Flags</pluralLabel>        <!-- WRONG: forbidden on custom settings -->
  <sharingModel>ReadWrite</sharingModel>          <!-- WRONG: forbidden -->
  <deploymentStatus>Deployed</deploymentStatus>   <!-- WRONG: forbidden -->
  <nameField>                                    <!-- WRONG: forbidden -->
    <label>Name</label>
    <type>Text</type>
  </nameField>
  <visibility>Public</visibility>
</CustomObject>
Errors:
Cannot specify: pluralLabel for CustomSettings
·
Cannot specify: sharingModel for CustomSettings
·
Cannot specify: deploymentStatus for CustomSettings
·
Cannot specify: nameField for CustomSettings
CORRECT — minimum valid custom setting:
xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
  <customSettingsType>Hierarchy</customSettingsType>
  <label>Feature Flags</label>
  <description>Per-profile and per-user toggles for beta features in the ordering app. Edited by admins in Setup.</description>
  <visibility>Public</visibility>
</CustomObject>
Note there is no
<fullName>
. A root-level one is tolerated and ignored, but omit it — the API name comes from the directory and filename.
<customSettingsType>List</customSettingsType>
deployed without needing the "Manage List Custom Settings Type" toggle in Setup. That toggle exists in some orgs, so if a List setting is rejected on a
customSettingsType
grounds in a different org, check Schema Settings before assuming the XML is wrong.

以下每个元素都会触发
Cannot specify: <element> for CustomSettings
错误:
禁止元素说明
<pluralLabel>
常规自定义对象必填,此处禁止。 要求完全相反。
<nameField>
List类型的设置中
Name
字段是隐式存在的
<deploymentStatus>
<sharingModel>
Custom Setting不是共享记录
<enableActivities>
<enableReports>
<enableHistory>
<enableSearch>
<validationRules>
请在Apex中执行这些验证
<recordTypes>
<compactLayouts>
错误示例——包含常规自定义对象的必填元素:
xml
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
  <customSettingsType>Hierarchy</customSettingsType>
  <label>Feature Flags</label>
  <pluralLabel>Feature Flags</pluralLabel>        <!-- 错误:Custom Setting禁止该元素 -->
  <sharingModel>ReadWrite</sharingModel>          <!-- 错误:禁止使用 -->
  <deploymentStatus>Deployed</deploymentStatus>   <!-- 错误:禁止使用 -->
  <nameField>                                    <!-- 错误:禁止使用 -->
    <label>Name</label>
    <type>Text</type>
  </nameField>
  <visibility>Public</visibility>
</CustomObject>
错误信息:
Cannot specify: pluralLabel for CustomSettings
·
Cannot specify: sharingModel for CustomSettings
·
Cannot specify: deploymentStatus for CustomSettings
·
Cannot specify: nameField for CustomSettings
正确示例——最小有效Custom Setting:
xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
  <customSettingsType>Hierarchy</customSettingsType>
  <label>Feature Flags</label>
  <description>订单应用中Beta功能的每个配置文件和每个用户切换开关。由管理员在Setup中编辑。</description>
  <visibility>Public</visibility>
</CustomObject>
注意此处没有
<fullName>
。根层级的
<fullName>
会被容忍但忽略,建议省略——API名称来自目录和文件名。
<customSettingsType>List</customSettingsType>
无需Setup中的“Manage List Custom Settings Type”开关即可部署。某些组织中存在该开关,因此如果List类型设置在其他组织中因
customSettingsType
被拒绝,请先检查Schema设置,不要直接认为XML有误。

3. List vs Hierarchy Decision (Tier 2)

3. List与Hierarchy类型选择(二级要求)

<customSettingsType>
has exactly two values, and the choice changes how rows are addressed.
Hierarchy
List
Use whenThe value can vary per profile or per user, with an org-wide fallbackThe setting is a small keyed reference table, the same for everyone
Row key
SetupOwnerId
(Organization, Profile, or User)
Name
ResolutionUser value → Profile value → org defaultLook up by
Name
Apex read
MySetting__c.getInstance()
/
getOrgDefaults()
MySetting__c.getValues('Key')
/
getAll()
Typical caseFeature flags, per-profile limits, debug togglesCountry codes, tax rates by region, integration endpoints by key
Default to
Hierarchy
when the user describes toggles, limits, or anything that "can be overridden." Choose
List
when they describe a lookup table with named rows.
If the user asks for a keyed reference table that should be deployable between orgs, a List custom setting is usually the wrong answer — its rows are data and will not travel with the deploy. Route to
platform-custom-metadata-type-generate
instead (Section 7).

<customSettingsType>
仅有两个值,选择不同的值会改变行的寻址方式。
Hierarchy
List
适用场景值可按配置文件或用户变化,且有组织级默认值设置是小型键值参考表,对所有用户一致
行键
SetupOwnerId
(组织、配置文件或用户)
Name
解析逻辑用户值 → 配置文件值 → 组织默认值
Name
查找
Apex读取方式
MySetting__c.getInstance()
/
getOrgDefaults()
MySetting__c.getValues('Key')
/
getAll()
典型用例功能标志、每个配置文件的限制、调试开关国家代码、按地区划分的税率、按键划分的集成端点
**默认选择
Hierarchy
**当用户描述切换开关、限制或任何“可覆盖”的内容时。当用户描述带有命名行的查找表时,选择
List
如果用户要求的键值参考表需要在组织间部署,List类型的Custom Setting通常不是正确选择——其行是数据,不会随部署迁移。请转至
platform-custom-metadata-type-generate
(第7节)。

4. Field Rules

4. 字段规则

Fields on a custom setting are ordinary
CustomField
components at
objects/<Name>__c/fields/<Field>__c.field-meta.xml
.
This skill owns the custom-setting-specific deltas only — the supported-type allowlist and the
fieldManageability
prohibition below. For everything generic (
<fullName>
derivation,
<label>
,
<description>
,
<inlineHelpText>
, precision/scale,
<length>
,
externalId
), follow
platform-custom-field-generate
.
Custom Setting上的字段是位于
objects/<Name>__c/fields/<Field>__c.field-meta.xml
的普通
CustomField
组件。
此技能仅负责Custom Setting特有的差异——支持的类型列表以及下文禁止的
fieldManageability
。对于所有通用规则(
<fullName>
派生、
<label>
<description>
<inlineHelpText>
、精度/比例、
<length>
externalId
),请遵循
platform-custom-field-generate

Supported Field Types

支持的字段类型

Checkbox
,
Currency
,
Date
,
DateTime
,
Email
,
Number
,
Percent
,
Phone
,
Text
,
TextArea
,
Url
required
,
unique
,
externalId
, and
defaultValue
are accepted on custom setting fields. Whether a given one applies to a given type is a generic field rule — defer to
platform-custom-field-generate
.
Checkbox
,
Currency
,
Date
,
DateTime
,
Email
,
Number
,
Percent
,
Phone
,
Text
,
TextArea
,
Url
required
,
unique
,
externalId
defaultValue
可用于Custom Setting字段。特定规则是否适用于特定类型属于通用字段规则——请参考
platform-custom-field-generate

Unsupported Field Types

不支持的字段类型

Picklist
,
MultiselectPicklist
,
LongTextArea
,
Html
,
Lookup
,
MasterDetail
,
AutoNumber
,
Location
,
Time
,
EncryptedText
, and Formula (a
<formula>
element on any type).
Every one of these fails with the same bare, uninformative string:
text
Invalid data type.
This error names neither field nor type. On a multi-field deploy, read
componentFailures[].fullName
from the
--json
output to find the culprit — do not guess.
Roll-up summary fields are structurally impossible here — a
Summary
needs a master-detail child, and
MasterDetail
is itself rejected on a custom setting. Don't generate one; the error text varies, so don't match on a specific string.
Picklist is the common trap. Users frequently ask for a picklist on a custom setting. It is not supported. Use
Text
and enforce the allowed values in Apex, or route the request to
platform-custom-metadata-type-generate
— CMDT does support Picklist.
Near-inversion vs CMDT:
Currency
works here but not on CMDT;
Picklist
/
LongTextArea
work on CMDT but not here. Never carry field-type assumptions across the two families.
Picklist
,
MultiselectPicklist
,
LongTextArea
,
Html
,
Lookup
,
MasterDetail
,
AutoNumber
,
Location
,
Time
,
EncryptedText
,以及Formula(任何类型上的
<formula>
元素)。
所有这些类型都会触发相同的模糊错误信息:
text
Invalid data type.
该错误未指定字段或类型。 在多字段部署中,从
--json
输出中读取
componentFailures[].fullName
来查找问题字段——不要猜测。
汇总字段在此处结构上不可能实现——
Summary
需要主明细子对象,而
MasterDetail
本身在Custom Setting上会被拒绝。请勿生成此类字段;错误文本各不相同,因此不要匹配特定字符串。
Picklist是常见陷阱。 用户经常要求在Custom Setting上使用Picklist,但它不受支持。请使用
Text
并在Apex中强制允许的值,或转至
platform-custom-metadata-type-generate
——CMDT支持Picklist。
与CMDT几乎相反:
Currency
在此处可用但在CMDT中不可用;
Picklist
/
LongTextArea
在CMDT中可用但在此处不可用。切勿在两者之间进行字段类型假设。

<fieldManageability>
is forbidden

<fieldManageability>
被禁止

That element belongs to CMDT fields only. On a custom setting field it fails with:
text
Field manageability cannot be set on this entity.

该元素仅属于CMDT字段。在Custom Setting字段上使用它会触发:
text
Field manageability cannot be set on this entity.

5. Visibility, Secrets, and the No-Silent-Downgrade Rule

5. 可见性、密钥与禁止静默降级规则

Protected
is org-type dependent

Protected
依赖组织类型

<visibility>Protected</visibility>
deploys only in a developer, sandbox, or scratch org. Anywhere else:
text
You can't set the visibility for a Custom Setting to Protected unless you are in a developer, sandbox, or scratch org.
<visibility>Protected</visibility>
仅能在开发者组织、沙盒或临时组织中部署。在其他环境中:
text
You can't set the visibility for a Custom Setting to Protected unless you are in a developer, sandbox, or scratch org.

The no-silent-downgrade rule — CRITICAL

禁止静默降级规则——至关重要

If
Protected
fails because of the org type, never "fix" it by switching to
Public
.
A silent downgrade turns a deliberate confidentiality choice into a world-readable component with no signal. Report it plainly: the org does not permit
Protected
, so the options are a dev/sandbox/scratch org or accepting
Public
— let the user decide. This applies to any visibility narrowing, not just this error.
如果因组织类型导致
Protected
部署失败,绝不要通过切换为
Public
来“修复”。
静默降级会将刻意的保密选择变为全局可读的组件,且无任何提示。请明确告知用户:该组织不允许使用
Protected
,因此选项是使用开发/沙盒/临时组织或接受
Public
——让用户决定。此规则适用于任何可见性限制的情况,不仅仅是此错误。

Secrets do not belong in a custom setting

密钥不应存储在Custom Setting中

Custom settings are not a secret store. Values are readable by anyone who can query the object, and
Protected
does not change that for code in the same namespace.
When a user asks to store an API key, password, token, client secret, or certificate in a custom setting:
  1. Warn prominently and first — before generating anything — that a custom setting is the wrong place for a credential and the value will be readable.
  2. Recommend the right component — a Named Credential with an External Credential for callout auth. Say plainly that this skill does not generate those.
  3. If the user still insists, comply — generate the setting but keep the warning in the response. Do not silently refuse, and do not silently obey.
Never route a secret to
Protected
visibility as a compromise: if
Protected
is unavailable (above), the no-silent-downgrade rule applies with full force, because the downgrade would publish the secret.

Custom Setting不是密钥存储。任何能够查询该对象的用户都可以读取值,且
Protected
不会改变同一命名空间中代码的读取权限。
当用户要求在Custom Setting中存储API密钥、密码、令牌、客户端密钥或证书时:
  1. 首先显著警告——在生成任何内容之前——Custom Setting不是存储凭据的正确位置,值会被读取。
  2. 推荐正确组件——用于调用认证的Named CredentialExternal Credential。明确说明此技能不生成这些组件。
  3. 如果用户仍坚持,按要求执行——生成设置但在响应中保留警告。请勿静默拒绝或静默执行。
绝不要将密钥请求转至
Protected
可见性作为折中方案:如果
Protected
不可用(如上所述),禁止静默降级规则完全适用,因为降级会公开密钥。

6. Setting Values Are Data, Not Metadata

6. 设置值是数据,而非元数据

A custom setting's rows cannot be deployed as XML. There is no
customMetadata/
-style folder for them. Only the object definition and its fields are metadata.
When a user asks to create a setting with values — "add a feature flag setting with Beta enabled for admins" — do all of the following:
  1. Generate the object and field XML as normal.
  2. State the limitation in one line: setting values are data, not metadata, so they are not deployed.
  3. Give ready-to-run commands inline in the chat response, fully substituted with the real object and field API names and the actual values — not a placeholder template, and not written to a file.
All three shapes below are verified working.
Custom Setting的行无法以XML形式部署。 没有类似
customMetadata/
的文件夹。只有对象定义及其字段是元数据。
当用户要求创建带值的设置(例如“添加一个功能标志设置,管理员启用Beta功能”)时,请执行以下所有操作:
  1. 正常生成对象和字段XML。
  2. 用一行说明限制:设置值是数据而非元数据,因此无法部署。
  3. 在聊天响应中提供可直接运行的命令,完全替换为真实的对象和字段API名称以及实际值——不要使用占位符模板,也不要写入文件。
以下三种格式均已验证可用。

Hierarchy — org-wide default row

Hierarchy——组织级默认行

Omit
SetupOwnerId
.
It defaults to the Organization Id, which is exactly the org-default row. No Id lookup is needed.
bash
sf data create record --sobject Feature_Flags__c \
  --values "Enable_Beta__c=true Max_Retries__c=3" \
  --target-org <alias>
省略
SetupOwnerId
它默认指向组织Id,正是组织级默认行。无需查找Id。
bash
sf data create record --sobject Feature_Flags__c \
  --values "Enable_Beta__c=true Max_Retries__c=3" \
  --target-org <alias>

Hierarchy — profile or user override

Hierarchy——配置文件或用户覆盖

This one does need an Id, so it is two steps. A user-level override uses the same shape with a
User
Id in place of the Profile Id (extrapolated from the profile case, not separately verified).
bash
sf data query --query "SELECT Id FROM Profile WHERE Name='System Administrator'" --target-org <alias>

sf data create record --sobject Feature_Flags__c \
  --values "SetupOwnerId=00eXXXXXXXXXXXXXXX Enable_Beta__c=false" \
  --target-org <alias>
An override row coexists with the org-default row; it does not replace it.
此格式需要Id,因此分为两步。用户级覆盖使用相同格式,将配置文件Id替换为用户Id(从配置文件案例推断,未单独验证)。
bash
sf data query --query "SELECT Id FROM Profile WHERE Name='System Administrator'" --target-org <alias>

sf data create record --sobject Feature_Flags__c \
  --values "SetupOwnerId=00eXXXXXXXXXXXXXXX Enable_Beta__c=false" \
  --target-org <alias>
覆盖行与组织级默认行共存;它不会替换默认行。

List — one row per key

List——每个键对应一行

Name
is the row key and is required.
bash
sf data create record --sobject Country_Codes__c \
  --values "Name='US' Iso_Code__c='USA' Dial_Prefix__c='+1'" \
  --target-org <alias>
Name
是行键,必填。
bash
sf data create record --sobject Country_Codes__c \
  --values "Name='US' Iso_Code__c='USA' Dial_Prefix__c='+1'" \
  --target-org <alias>

Quoting

引号规则

Wrap the whole
--values
argument in double quotes; single-quote any value with a space or shell-special character (
Environment_Label__c='org default'
). Plain numbers, booleans, and Ids need no inner quotes.
将整个
--values
参数用双引号包裹;对包含空格或Shell特殊字符的值使用单引号(例如
Environment_Label__c='org default'
)。纯数字、布尔值和Id不需要内部引号。

Consuming a setting in Apex

在Apex中使用设置

Values are read through the generated typed class — cached, so reads cost no SOQL and are safe inside loops and triggers. For a Hierarchy setting:
apex
Feature_Flags__c cfg = Feature_Flags__c.getInstance();        // running user: user → profile → org default
Feature_Flags__c org = Feature_Flags__c.getOrgDefaults();     // org-default row only, no hierarchy
Feature_Flags__c forProfile = Feature_Flags__c.getInstance(profileId);  // a User Id works too
Boolean beta = cfg.Enable_Beta__c;
getInstance()
and
getOrgDefaults()
never return null (API ≥ 22) — a missing record comes back as an empty row, so test
org.Id != null
when you need to know whether a real record actually exists. For a List setting, use
getValues('Key')
for one row or
getAll()
for the
Map<String, Feature_Flags__c>
of every row.
通过生成的类型化类读取值——已缓存,因此读取操作不消耗SOQL,可安全用于循环和触发器中。对于Hierarchy类型的设置:
apex
Feature_Flags__c cfg = Feature_Flags__c.getInstance();        // 当前用户:用户值 → 配置文件值 → 组织默认值
Feature_Flags__c org = Feature_Flags__c.getOrgDefaults();     // 仅组织级默认行,无层级逻辑
Feature_Flags__c forProfile = Feature_Flags__c.getInstance(profileId);  // 用户Id也适用
Boolean beta = cfg.Enable_Beta__c;
getInstance()
getOrgDefaults()
永远不会返回null(API ≥ 22)——缺失的记录会返回空行,因此当你需要知道实际记录是否存在时,请测试
org.Id != null
。对于List类型的设置,使用
getValues('Key')
获取单行,或使用
getAll()
获取所有行的
Map<String, Feature_Flags__c>

The in-transaction DML rule

事务内DML规则

Populating or changing values is runtime DML (Apex
insert
/
update
/
upsert
, or the
sf
commands above) — there is no metadata path. That is the operational face of "values are data," and it has two consequences worth stating to the user:
  • Writes count against DML governor limits; reads do not. In a trigger over 200 records, never
    upsert
    the setting once per record — hoist the write out of the loop and do it once.
  • Cross-transaction propagation lags. After a write, other transactions may briefly read the previous value while the org cache propagates; within the same transaction the new value is visible immediately.

填充或修改值是运行时DML(Apex的
insert
/
update
/
upsert
,或上述
sf
命令)——没有元数据路径。这是“值是数据”的操作层面体现,有两个值得向用户说明的后果:
  • 写入操作消耗DML governor限制;读取操作不消耗。 在处理200条记录的触发器中,绝不要每条记录执行一次
    upsert
    设置——将写入操作移出循环,只执行一次。
  • 跨事务传播存在延迟。 写入后,其他事务可能会短暂读取旧值,直到组织缓存完成传播;同一事务内可立即看到新值。

7. Choosing the Right Component

7. 选择正确的组件

Before generating, confirm a custom setting is actually what the user needs. If it is not, say so and name the right skill rather than building the wrong thing.
If the config is…UseWhy
Admin-editable per profile/user, or a small keyed table that stays in one orgCustom Setting (this skill)Values are data; they do not travel with a deploy
Reference data that must deploy between orgs with its records
platform-custom-metadata-type-generate
CMDT records are metadata and are deployable
Business records users create and edit at runtime
platform-custom-object-generate
Custom settings are configuration, not transactional data
Translatable UI textCustom Label — this skill does not generate itLabels are the supported translation surface
Credentials, API keys, tokens, endpoints with authNamed Credential / External Credential — this skill does not generate themSee Section 5
A permission check in Apex or a flowCustom Permission — this skill does not generate itBoolean access checks belong in the permission model
The distinction that matters most: CMDT records deploy, custom setting values do not. If the user says "and it should ship with these values" or "the same in every org," that is a CMDT request.

生成之前,请确认Custom Setting确实是用户需要的组件。如果不是,请说明并指明正确的技能,而非构建错误的组件。
如果配置是…使用原因
管理员可编辑的按配置文件/用户划分的设置,或仅在一个组织中使用的小型键值表Custom Setting(此技能)值是数据;不会随部署迁移
必须在组织间部署且包含记录的参考数据
platform-custom-metadata-type-generate
CMDT记录是元数据,可部署
用户在运行时创建和编辑的业务记录
platform-custom-object-generate
Custom Setting是配置,而非事务数据
可翻译的UI文本Custom Label——此技能不生成标签是支持翻译的载体
凭据、API密钥、令牌、带认证的端点Named Credential / External Credential——此技能不生成详见第5节
Apex或流中的权限检查Custom Permission——此技能不生成布尔值权限检查属于权限模型
最关键的区别:CMDT记录可部署,Custom Setting值不可部署。 如果用户说“并且它应该附带这些值”或“在每个组织中都相同”,这是CMDT请求。

8. Common Deployment Errors

8. 常见部署错误

Error MessageCauseFix
Must specify a non-empty plural label for the CustomObject
<customSettingsType>
is missing, so this is being validated as a regular custom object
Add
<customSettingsType>
. Do NOT add
<pluralLabel>
(Section 2)
Cannot specify: pluralLabel for CustomSettings
<pluralLabel>
present
Remove it — required on custom objects, forbidden here
Cannot specify: <element> for CustomSettings
(
<element>
=
nameField
,
sharingModel
,
deploymentStatus
,
validationRules
,
recordTypes
, or
compactLayouts
)
A custom-object-only element is presentRemove it (enforce validation logic in Apex instead)
Invalid data type.
Unsupported field type (Section 4)Read
componentFailures[].fullName
to find the field; switch to a supported type
Field manageability cannot be set on this entity.
<fieldManageability>
on a setting field
Remove it — CMDT only
You can't set the visibility for a Custom Setting to Protected unless you are in a developer, sandbox, or scratch org.
Protected
in a production-like org
Report to the user; never silently switch to
Public
(Section 5)
The
Cannot specify:
suffix is
for CustomSettings
(one word) versus CMDT's
for Custom Metadata Type
, and the visibility error uses
for a Custom Setting
(spaced, singular). Do not assume a shared template when matching these strings.

错误信息原因修复方案
Must specify a non-empty plural label for the CustomObject
缺少
<customSettingsType>
,因此被当作常规自定义对象验证
添加
<customSettingsType>
请勿添加
<pluralLabel>
(第2节)
Cannot specify: pluralLabel for CustomSettings
存在
<pluralLabel>
移除该元素——自定义对象必填,此处禁止
Cannot specify: <element> for CustomSettings
<element>
=
nameField
,
sharingModel
,
deploymentStatus
,
validationRules
,
recordTypes
compactLayouts
存在仅适用于自定义对象的元素移除该元素(改为在Apex中执行验证逻辑)
Invalid data type.
使用了不支持的字段类型(第4节)读取
componentFailures[].fullName
查找字段;切换为支持的类型
Field manageability cannot be set on this entity.
在设置字段上使用了
<fieldManageability>
移除该元素——仅适用于CMDT
You can't set the visibility for a Custom Setting to Protected unless you are in a developer, sandbox, or scratch org.
在类生产组织中使用了
Protected
告知用户;绝不要静默切换为
Public
(第5节)
Cannot specify:
的后缀在Custom Setting中是
for CustomSettings
(一个单词),而在CMDT中是
for Custom Metadata Type
;可见性错误使用
for a Custom Setting
(空格分隔,单数)。匹配这些字符串时不要假设存在共享模板。

9. Verification Checklist

9. 验证清单

Before generating custom setting XML, verify:
生成Custom Setting XML之前,请验证:

Component Identity Checks CRITICAL

组件身份检查(至关重要)

  • Is
    <customSettingsType>
    present and set to
    Hierarchy
    or
    List
    ?
  • Is the choice between Hierarchy and List justified by the request (overridable vs keyed table)?
  • If a deploy reported
    Must specify a non-empty plural label for the CustomObject
    , was it fixed by adding
    <customSettingsType>
    rather than by adding
    <pluralLabel>
    ?
  • After a successful deploy of a new setting, was it confirmed to actually be a custom setting? Inspecting the XML cannot catch this failure, because the wrong-component outcome deploys green. Run
    sf sobject describe --sobject <Name>__c --target-org <alias>
    and verify
    customSetting
    is
    true
    .
  • 是否存在
    <customSettingsType>
    且设置为
    Hierarchy
    List
  • Hierarchy与List的选择是否符合用户请求(可覆盖 vs 键值表)?
  • 如果部署报告
    Must specify a non-empty plural label for the CustomObject
    ,是否通过添加
    <customSettingsType>
    而非
    <pluralLabel>
    修复?
  • 新设置部署成功后,是否确认它确实是Custom Setting?仅检查XML无法发现此类失败,因为错误组件的部署会显示成功。运行
    sf sobject describe --sobject <Name>__c --target-org <alias>
    并验证
    customSetting
    true

Syntactic Checks

语法检查

  • Are
    <label>
    and
    <visibility>
    present?
  • Is
    <description>
    present and specific about what the setting controls?
  • Is
    <pluralLabel>
    ABSENT?
  • Are
    <nameField>
    ,
    <sharingModel>
    , and
    <deploymentStatus>
    ABSENT?
  • Are
    <enableActivities>
    ,
    <enableReports>
    ,
    <enableHistory>
    , and
    <enableSearch>
    ABSENT?
  • Are
    <validationRules>
    ,
    <recordTypes>
    , and
    <compactLayouts>
    ABSENT?
  • Does the filename match the intended API name, ending in
    __c
    ?
  • 是否存在
    <label>
    <visibility>
  • 是否存在
    <description>
    且明确说明设置控制的内容?
  • 是否不存在
    <pluralLabel>
  • 是否不存在
    <nameField>
    <sharingModel>
    <deploymentStatus>
  • 是否不存在
    <enableActivities>
    <enableReports>
    <enableHistory>
    <enableSearch>
  • 是否不存在
    <validationRules>
    <recordTypes>
    <compactLayouts>
  • 文件名是否与预期API名称匹配,以
    __c
    结尾?

Field Checks

字段检查

  • Is every field type in the supported list (Section 4)?
  • Is
    Picklist
    absent? (unsupported — use
    Text
    , or route to CMDT)
  • Is every
    <formula>
    element absent? (formulas are unsupported)
  • Is
    <fieldManageability>
    ABSENT on every field?
  • Do generic field attributes follow
    platform-custom-field-generate
    ?
  • 所有字段类型是否都在支持列表中(第4节)?
  • 是否不存在
    Picklist
    ?(不支持——使用
    Text
    或转至CMDT)
  • 是否不存在任何
    <formula>
    元素?(公式不支持)
  • 所有字段是否不存在
    <fieldManageability>
  • 通用字段属性是否遵循
    platform-custom-field-generate

Values Checks

值检查

  • If the user asked for values, was the data-not-metadata limitation stated explicitly?
  • Were
    sf
    commands given inline in the response, fully substituted with real API names and real values — not written to a file, not left as a template?
  • For a Hierarchy org default, is
    SetupOwnerId
    omitted rather than guessed?
  • For a List row, is
    Name
    supplied?
  • 如果用户要求设置值,是否明确说明数据而非元数据的限制?
  • 是否在响应中直接提供
    sf
    命令,完全替换为真实API名称和值——未写入文件,未使用模板?
  • 对于Hierarchy组织级默认值,是否省略了
    SetupOwnerId
    而非猜测?
  • 对于List行,是否提供了
    Name

Consumption Checks

使用检查

  • If the user asked how to read the setting, was an Apex snippet given using the generated accessors (
    getInstance
    /
    getOrgDefaults
    for Hierarchy,
    getValues
    /
    getAll
    for List)?
  • Was the in-transaction DML rule stated — writes are DML that count against limits (bulkify, hoist out of loops), reads are free, and cross-transaction cache propagation lags?
  • 如果用户询问如何读取设置,是否提供了使用生成的访问器的Apex代码片段(Hierarchy使用
    getInstance
    /
    getOrgDefaults
    ,List使用
    getValues
    /
    getAll
    )?
  • 是否说明了事务内DML规则——写入是消耗限制的DML(批量处理,移出循环),读取免费,跨事务缓存传播存在延迟?

Security Checks CRITICAL

安全检查(至关重要)

  • If the request involves a secret, key, token, or password, was the warning given before generating, with a Named Credential recommended?
  • Was
    Protected
    left intact rather than silently downgraded to
    Public
    on an org-type failure?
  • 如果请求涉及密钥、令牌或密码,是否在生成之前给出警告,并推荐Named Credential?
  • 当因组织类型导致失败时,是否保留
    Protected
    而非静默降级为
    Public

Component-Choice Checks

组件选择检查

  • If the values must deploy between orgs, was
    platform-custom-metadata-type-generate
    recommended instead?
  • If the request is really business records, was
    platform-custom-object-generate
    recommended instead?
  • 如果值需要在组织间部署,是否推荐使用
    platform-custom-metadata-type-generate
  • 如果请求实际是业务记录,是否推荐使用
    platform-custom-object-generate