platform-value-set-generate
Use to create, generate, or validate a Salesforce GlobalValueSet (reusable picklist shared across fields) or customize a StandardValueSet (built-in picklists like Industry, Lead Source, Opportunity Stage). Trigger on global/standard value set, reusable picklist, .globalValueSet-meta.xml or .standardValueSet-meta.xml, or deploy errors adding values to a standard picklist. DO NOT TRIGGER for a one-off inline picklist on a single field with no reuse — use platform-custom-field-generate.
- 5,053
- installs
- 0 up / 0 down, score 0.00
- votes
- 1,109
- repo stars
- Updated
- less than a month ago
- In the catalog since
- 1 Oct 2026
- From
- forcedotcom/sf-skills
Skill instructions
Rendered from the published SKILL.md, 297 lines.
Overview
Generates and validates the two reusable picklist value-set metadata types — GlobalValueSet (a new reusable set shared across fields) and StandardValueSet (customizing a built-in catalog picklist like Industry or Lead Source) — and wires a CustomField to one via <valueSetName>.
For authoritative Metadata API type, field, and enum details beyond this skill, use the platform-metadata-api-context-get skill.
Scope
- In scope: creating a GlobalValueSet, customizing a StandardValueSet, referencing either from a field, and the related deployment errors.
- Out of scope: a one-off inline picklist on a single field with no reuse → use
platform-custom-field-generate(inline<valueSetDefinition>). Generating the field that references a value set is alsoplatform-custom-field-generate's job; this skill produces the value set itself.
Two different metadata types — do not confuse them:
| Concern | GlobalValueSet | StandardValueSet |
|---|---|---|
| Folder | globalValueSets/ |
standardValueSets/ |
| File suffix | .globalValueSet-meta.xml |
.standardValueSet-meta.xml |
| Root element | <GlobalValueSet> |
<StandardValueSet> |
| Name source | filename (dev name) | <fullName> = fixed catalog name |
| Value element | <customValue> |
<standardValue> |
| Can add NEW values? | Yes | Yes — copy the attribute pattern of an existing value |
| Can create a new NAME? | Yes | No — only the fixed catalog |
* wildcard in package.xml |
Supported | Not supported |
Specification
1. Purpose
This document defines the mandatory constraints for generating value-set metadata XML. The agent must verify these constraints before outputting XML to prevent Metadata API deployment errors.
- GlobalValueSet — a reusable, named set of picklist values defined once and referenced by any number of picklist/multi-select fields. Use when the same value list is shared across multiple fields.
- StandardValueSet — the value list behind a Salesforce-defined standard picklist (Industry, Lead Source, etc.). You can only customize the fixed catalog of named sets, so you cannot invent a new set name, but you can modify existing values and add new ones.
2. GlobalValueSet — Syntactic Essentials
File: globalValueSets/<DeveloperName>.globalValueSet-meta.xml
The developer name comes from the filename, not a <fullName> tag.
Required Elements
| Element | Requirement | Notes |
|---|---|---|
<masterLabel> |
Required | UI label for the value set |
<sorted> |
Required | true = alphabetize values in the UI; false = preserve listed order |
<customValue> |
Required (≥1) | One per value (see below) |
<customValue> Sub-Elements
| Sub-element | Requirement | Notes |
|---|---|---|
<fullName> |
Required | The value's API name. Use the value text as the user spelled it — spaces are allowed and must be preserved (e.g. Closed Won, not Closed_Won). Must start with a letter. This is a value name, NOT a field API name, so do not append __c or replace spaces with underscores. |
<default> |
Optional | At most one value true. Omit it (or use false) on the rest — it is not required on every value. |
<label> |
Required | UI label for the value |
<color> |
Optional | Hex color, e.g. #FF0000 |
<isActive> |
Optional | Omit (active) or false to deactivate |
<description> |
Optional | Per-value description |
The __gvs Suffix — do NOT use it in metadata
Rule: reference a GlobalValueSet by its bare developer name. Never add __gvs.
In API 57.0+ orgs the platform stores/displays a GlobalValueSet's developer name with a __gvs suffix internally, but the Metadata API (deploy and retrieve) always uses the bare name — <valueSetName>Priority_Levels</valueSetName>, not Priority_Levels__gvs. The suffix was briefly emitted by a Winter '23 change that caused deploy failures and was patched out. So:
- The file is
globalValueSets/Priority_Levels.globalValueSet-meta.xml— no__gvsin the filename. - A field references it as
<valueSetName>Priority_Levels</valueSetName>— no__gvs. - If a retrieve shows
Priority_Levels__gvsin the org or you see a "returned from org but not found in local project" warning, that's the expected org-storage display — keep your local metadata on the bare name.
CORRECT — GlobalValueSet
<?xml version="1.0" encoding="UTF-8"?>
<GlobalValueSet xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>Priority Levels</masterLabel>
<sorted>false</sorted>
<customValue>
<fullName>Critical</fullName>
<default>false</default>
<label>Critical</label>
</customValue>
<customValue>
<fullName>High</fullName>
<default>false</default>
<label>High</label>
</customValue>
<customValue>
<fullName>Medium</fullName>
<default>true</default>
<label>Medium</label>
</customValue>
<customValue>
<fullName>Low</fullName>
<default>false</default>
<label>Low</label>
</customValue>
</GlobalValueSet>
INCORRECT — GlobalValueSet
<GlobalValueSet xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Priority_Levels</fullName> <!-- WRONG: name comes from the filename -->
<masterLabel>Priority Levels</masterLabel>
<!-- WRONG: <sorted> is required and missing -->
<standardValue> <!-- WRONG: GVS uses <customValue>, not <standardValue> -->
<fullName>Critical</fullName>
</standardValue>
</GlobalValueSet>
Errors: missing required sorted; unknown element standardValue; root fullName is rejected because the name is derived from the filename.
3. StandardValueSet — Syntactic Essentials CRITICAL
Show the whole skill (177 more lines)
File: standardValueSets/<Name>.standardValueSet-meta.xml
HARD CONSTRAINTS — read before generating
- A StandardValueSet name must come from the fixed catalog of named standard value sets. You cannot create a new StandardValueSet name. You can add a new value to an existing standard set, but copy the full attribute pattern of an existing value in that set (for example
closed,forecastCategory,probabilityandwononOpportunityStage), because omitted attributes are filled with platform defaults that can be wrong. - The root carries a
<fullName>whose value is the fixed enum name (e.g.Industry), NOT amasterLabel. The filename must match this name. - Values are
<standardValue>entries — not<customValue>. - A StandardValueSet write REPLACES the whole set. Send every existing value and change only what the request names. Read the current set first (grounding MCP or a retrieve), then include a
<standardValue>block for every existing value, with the requested activations, deactivations, relabels or additions applied. A value you leave out is deactivated on the field: a deploy that named onlyWebinCaseOriginleftEmail,PhoneandAgentforceinactive. Never send only the named values, even when the set is large (for example all 30+Industryentries). Request wording such as "keep only X active" means set X active and every other value inactive, so state that intent in the result. Verify by reading the set back and diffing it against the read taken before the write.
<standardValue> — Modifiable Sub-Elements
| Sub-element | Modifiable? | Notes |
|---|---|---|
<fullName> |
Identifies the value | An existing value, or a new one you are adding |
<label> |
Yes | Relabel the value's UI text |
<isActive> |
Yes | false deactivates; omit or true keeps active |
<default> |
Yes | At most one value true |
<groupingString> |
Yes | Category grouping (used by some standard picklists) |
Canonical StandardValueSet Names (partial)
Industry, LeadSource, OpportunityStage, OpportunityType, AccountType, AccountRating, LeadStatus, CaseStatus, CaseOrigin, CasePriority, CaseReason, TaskStatus, TaskPriority, QuoteStatus, Product2Family, Salutation, AccountOwnership, ContractStatus, OrderStatus, PartnerRole.
Full appendix: the complete list of valid standard value set names is at
https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/standardvalueset_names.htm. If the name is not in that appendix, it is not a StandardValueSet — it is either a GlobalValueSet or an inline CustomField picklist.
CORRECT — StandardValueSet (the complete set, with the requested change applied)
<?xml version="1.0" encoding="UTF-8"?>
<StandardValueSet xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Industry</fullName>
<standardValue>
<fullName>Technology</fullName>
<default>false</default>
<label>Technology</label>
<isActive>true</isActive>
</standardValue>
<standardValue>
<fullName>Agriculture</fullName>
<default>false</default>
<label>Agriculture</label>
<isActive>false</isActive> <!-- deactivated, but kept in the set -->
</standardValue>
<!-- ... every other existing standardValue entry repeated unchanged ... -->
</StandardValueSet>
INCORRECT — StandardValueSet
<StandardValueSet xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>Industry</masterLabel> <!-- WRONG: StandardValueSet uses <fullName>, not masterLabel -->
<customValue> <!-- WRONG: uses <standardValue>, not customValue -->
<fullName>Renewable Energy</fullName>
<label>Renewable Energy</label>
</customValue>
</StandardValueSet>
Errors: unknown element masterLabel/customValue for a StandardValueSet.
4. Never Invent Values — Verify, Don't Hallucinate CRITICAL
When customizing a StandardValueSet (or extending a shared GlobalValueSet), never invent the existing value list of a standard picklist. Existing values must be repeated exactly as the org has them, and a new value is added only when the request names it.
For well-known standard picklists you already know the canonical values (e.g. Industry, LeadSource, OpportunityStage). When you are unsure which values exist, you can confirm them against the live org — but treat lookup as a confirmation step, not a required first call:
- Grounding MCP (if available) exposes
search_metadataandquery_metadatato look up live metadata. Use them to read the complete current set, because a write must repeat every existing value with its exact<fullName>/<label>. - CLI fallback — query the Tooling API directly:
sf data query --use-tooling-api \
--query "SELECT MasterLabel, Metadata FROM StandardValueSet WHERE MasterLabel = '<name>'"
The point is the output, not the lookup: the written set must contain every existing value unchanged, plus only the changes the request names. Do not invent values the request did not ask for. (This pairs with rule 4 in §3: a write replaces the whole set.)
5. Referencing a Value Set from a CustomField
A picklist/multi-select CustomField references a value set via <valueSetName> inside <valueSet> (instead of an inline <valueSetDefinition>).
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Priority__c</fullName>
<label>Priority</label>
<type>Picklist</type>
<valueSet>
<restricted>true</restricted>
<valueSetName>Priority_Levels</valueSetName> <!-- bare developer name, NO __gvs; see §2 -->
</valueSet>
</CustomField>
- For a GlobalValueSet,
<valueSetName>is the bare developer name (e.g.Priority_Levels) — never add__gvs. The suffix is an org-storage display artifact; the Metadata API uses the bare name for both deploy and retrieve (see §2). - A field bound to a value set must not also declare an inline
<valueSetDefinition>— choose one or the other.
6. Validation Rules
The agent must reject and explain — not silently "fix" by inventing metadata — the following:
| Violation | Action / Message |
|---|---|
| Create a NEW StandardValueSet name | Reject. The name must be in the standard catalog appendix. Otherwise it is a GlobalValueSet. |
| Value set developer name with spaces / invalid chars | Convert spaces to underscores; must start with a letter; alphanumeric + underscore only. Priority Levels → Priority_Levels. (This applies to the value SET name and the field API name — NOT to individual <customValue><fullName> values, which keep spaces as written.) |
Duplicate value fullName within one set |
Reject. Each fullName must be unique within the value set. |
More than one <default>true</default> |
Reject. At most one default value per set. |
Adding a value to a standard set
"Add a
Cryptocurrencyvalue to the Industry picklist."
This is allowed. Read the complete current Industry set, then write it back with every existing value unchanged plus one new <standardValue> for Cryptocurrency. Copy the attribute pattern of an existing value in the set, because omitted attributes get platform defaults that can be wrong.
7. Deployment Ordering
A value set must deploy before any CustomField that references it.
- Deploy the
GlobalValueSet/StandardValueSetfirst, then the CustomField whose<valueSetName>points at it. - A field referencing a value set that does not yet exist fails with
valueSetName ... does not exist(or a "not found" error). - In
package.xml:GlobalValueSetsupports the*wildcard;StandardValueSetdoes not — list each standard set member explicitly.
8. Common Deployment Errors
| Error / Symptom | Cause | Fix |
|---|---|---|
| Other values of a standard picklist became inactive after a deploy | The deploy listed only some values, and a write replaces the whole set | Resend the complete set with every existing value (§3 rule 4) |
Required field missing: sorted |
GlobalValueSet missing <sorted> |
Add <sorted>true</sorted> or <sorted>false</sorted> |
Unknown element masterLabel (StandardValueSet) |
Used masterLabel instead of fullName |
StandardValueSet root uses <fullName> = catalog name |
Unknown element customValue (StandardValueSet) |
Used customValue instead of standardValue |
Use <standardValue> in standard sets |
valueSetName ... does not exist |
Field deployed before its value set, or __gvs wrongly added to the reference |
Deploy the value set first; reference it by the bare developer name with NO __gvs (§2) |
| Duplicate value name | Two <customValue> entries share a fullName |
Make each fullName unique within the set (spaces in a value name are allowed — do NOT underscore them) |
Verification Checklist
Before generating value-set XML, verify:
Type Selection
- Is this a reusable set shared across fields (GlobalValueSet) or a built-in standard picklist (StandardValueSet)?
- If StandardValueSet: is the name in the standard catalog appendix? If not, it must be a GlobalValueSet or inline picklist.
GlobalValueSet Checks
- Is the root
<GlobalValueSet>with namespacehttp://soap.sforce.com/2006/04/metadata? - Is
<masterLabel>present? - Is
<sorted>present (trueorfalse)? - Is there at least one
<customValue>, each with<fullName>and<label>(at most one carrying<default>true</default>)? - Is there NO root
<fullName>(name comes from the filename)? - When referencing from a field, is
<valueSetName>the bare developer name with NO__gvssuffix?
StandardValueSet Checks CRITICAL
- Did you read the complete current set (grounding
search_metadata/query_metadata/ Tooling API / retrieve) so every existing value is repeated exactly? - Is the root
<StandardValueSet>with the correct namespace? - Does the root use
<fullName>set to the fixed catalog name (NOTmasterLabel)? - Are values
<standardValue>entries (NOTcustomValue)? - Does the written set contain every existing value, with only the changes the request names applied?
- Did you avoid a new set name, and for any new value did you copy the attribute pattern of an existing value?
Shared Checks
- At most one value has
<default>true</default>? - Are all value
fullNames unique within the set? (Spaces in a value name are fine — preserve them as written; only the value-SET developer name and field API name use underscores.) - Does the value set deploy BEFORE any CustomField that references it?
- Does the filename match the intended name?