npx skills add ...
npx skills add forcedotcom/sf-skills --skill platform-custom-lightning-type-generate
Use this skill when users need to create Custom Lightning Types (CLTs) for Einstein Agent actions or structured input/output schemas. Trigger when users mention CLT, Custom Lightning Types, JSON schemas for agents, type definitions, lightning__objectType, or editor/renderer configurations. For widget renditions that combine a CLT with a Widget bundle, use the platform-lightning-type-widget-coordinate orchestrator instead. This is complex - always use this skill for CLT work.
npx skills add forcedotcom/sf-skills --skill platform-custom-lightning-type-generate
Use this skill when you need to:
Custom Lightning Types (CLTs) are JSON Schema-based type definitions used by the Lightning Platform (including Einstein Agent actions) to describe structured inputs/outputs and drive editor/renderer experiences.
"lightning:type": "c__<CLTName>". That string is the referenced type’s lightning:type value / FQN / registered identifier — not the JSON Schema title.lightning:type identifiers.@apexClassType/...) when the structure already exists server-side and you want the Apex class to define the shape."$schema" field in schema.json
$schema declaration."type": "object""title""lightning:type": "lightning__objectType""unevaluatedProperties": false"unevaluatedProperties" is enforced as false by the CLT metaschema. Do not set it to true."examples" when "unevaluatedProperties": false is set.properties) MUST NOT set "lightning:type": "lightning__objectType".
c__<CLTName> syntax.items keyword entirely. Treat items as disallowed by default.properties):
"lightning:type": "lightning__listType""items""type": "array""type": "array""lightning:type": "lightning__listType""items""unevaluatedProperties": false is set, any unknown keyword will fail validation. Prefer removing keywords over relaxing strictness.title, description (optional), and lightning:type set to @apexClassType/....type, properties, required, or unevaluatedProperties.attributes in the root override — this overrides any prompt wording to the contrary. Since the schema has no properties block, there is nothing for {!$attrs.<name>} to resolve against — unevaluatedProperties: false will reject any attribute key (e.g. "You can't add the flightId property ... because the unevaluatedProperties keyword value is set to false"). Use "componentOverrides": { "$": { "definition": "c/<yourComponent>" } } with no attributes key at all. If the user's prompt explicitly asks for attribute mappings to specific fields (e.g. "with attribute mappings for fieldA, fieldB") on an Apex-class CLT renderer/editor, do NOT comply literally — omit attributes from the root override anyway, and say so in your response (e.g. "Note: attribute mappings were omitted because the backing type is an Apex-class CLT, which has no properties block to bind against").$(…) or backticks), process substitution (<(…), >(…)), brace expansion ({a,b,c} or {1..N}), or eval / exec. Vibes forces manual approval on these patterns even under Bypass mode and stalls the eval. Emit separate commands (mkdir -p a && mkdir -p b) or print each value with its own command and reason about the output rather than capturing it in a shell variable.sfdc_cms where not permitted).lightning:type is exactly lightning__objectType.When you need the full list of supported primitive lightning:type identifiers, their constraints, and the allowed property-level keywords, read assets/primitive-types-and-constraints.md in this skill's directory.
schema.json
"$schema" at the topproperties using valid primitive lightning:type identifiers."lightning:type": "c__<CLTName>" to reference another CLT@apexClassType/... when structure exists server-side.@apexClassType/...) for deploy-safe nested structures.items; avoid lightning:type on nested arrays).lightning:type spellings (for example, use lightning__richTextType, not misspelled variants).editor.json (only if custom UI is required)
editor object with editor.componentOverrides and editor.layout.
editor object.editor.componentOverrides for component overrides.editor.layout for layout.propertyRenderers or view — these are legacy keys. Always use componentOverrides and layout instead.editor.componentOverrides["$"] = { "definition": "c/<yourEditorComponent>", "attributes": { ... } }{!$attrs.<name>} syntax: e.g. "attributes": { "myField": "{!$attrs.value}" } so the runtime binds schema values to your component's attributes.<name> in {!$attrs.<name>} must be a property defined in your type schema. For example, if your schema has a property called temperature, use {!$attrs.temperature}, not {!$attrs.value} unless value is an actual property.editor.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/<...>" }es_property_editors/inputText, es_property_editors/inputNumber, es_property_editors/inputRichText, es_property_editors/inputImage, es_property_editors/inputTextarea. Do not use es_property_editors/inputList.lightning__listType properties): Use a collection-level override so the list is edited by a custom component: collection.editor.componentOverrides["$"] = { "definition": "c/<yourCollectionEditorComponent>" }. Alternatively, use editor.layout with lightning/propertyLayout and attributes.property = "<listPropertyName>" for default list editing.editor.layout.definition = "lightning/verticalLayout"editor.layout.children[*].definition = "lightning/propertyLayout" with attributes.property = "<propertyName>"lightning/propertyLayout only accepts the property attribute. Do NOT add label, title, or any other attributes — these will fail validation with additionalProperties: false errors.es_property_editors/inputList.itemSchema attributes.renderer.json (only if custom UI or widget rendition is required)
renderer object with renderer.componentOverrides and renderer.layout.
renderer object.renderer.componentOverrides for component overrides.renderer.layout for layout.propertyRenderers or view — these are legacy keys. Always use componentOverrides and layout instead."definition": "@widget/c/<widgetDeveloperName>") and maps CLT schema properties to widget attributes via {!$attrs.<schemaPropertyName>}. Do NOT duplicate the widget body inside renderer.json. See references/widget-rendition.md for the full shape, binding rules, and constraints. For the full Apex → Lightning Type → Widget pipeline, use the platform-lightning-type-widget-coordinate orchestrator instead of this skill.renderer.componentOverrides["$"] = { "definition": "c/<yourRendererComponent>", "attributes": { ... } }{!$attrs.<name>} in attribute mappings when binding schema data to custom renderer component attributes.{!$attrs.propertyName} must reference properties that actually exist in your type schema. Referencing non-existent properties will fail validation.renderer.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/outputText" | "es_property_editors/outputNumber" | "es_property_editors/outputImage" | ... }. Valid renderer components (examples): es_property_editors/outputText, es_property_editors/outputNumber, es_property_editors/outputImage. Avoid input-style components in the renderer.renderer.layout.definition = "lightning/verticalLayout"renderer.layout.children[*].definition = "lightning/propertyLayout" with attributes.property = "<propertyName>"lightning/propertyLayout only accepts the property attribute. Do NOT add label, title, or any other attributes.lightning__listType properties): Use collection.renderer.componentOverrides["$"] = { "definition": "c/<yourListRendererComponent>" } or es_property_editors/genericListTypeRenderer to render the list.lightningTypes/<TypeName>/schema.jsonlightningTypes/<TypeName>/lightningDesktopGenAi/editor.jsonlightningTypes/<TypeName>/lightningDesktopGenAi/renderer.json
For Gen AI / Copilot the standard path is lightningDesktopGenAi/. Other targets (e.g. Experience Builder, Mobile Copilot, Enhanced Web Chat) use different subfolders when supported: experienceBuilder/, lightningMobileGenAi/, enhancedWebChat/.lightningTypes/<TypeName>/renderer.json-meta.xml files:
c/<componentName> used in editor.json): The LWC's -meta.xml file must include <target>lightning__AgentforceInput</target>c/<componentName> used in renderer.json): The LWC's -meta.xml file must include <target>lightning__AgentforceOutput</target>Invalid target configuration. To use 'c/componentName' as a renderer/editor, your js-meta.xml file must include valid target 'lightning__AgentforceOutput/Input'.-meta.xml for a renderer component:
| Error / Symptom | Likely Cause | Fix |
|---|---|---|
| Schema validation fails due to unknown keyword | unevaluatedProperties: false + disallowed keyword (commonly examples, items) | Remove the offending keyword; keep schema minimal |
| Nested object validation failure | Org/channel validation rejects nested object typing in LightningTypeBundle | Use CLT reference (c__<CLTName>) or Apex class types |
| Invalid CLT reference | Referenced CLT doesn't exist in org or incorrect syntax | Deploy the referenced CLT first; c__<CLTName> must match the referenced type’s lightning:type value / FQN / registered identifier, not title |
Invalid or misspelled lightning:type (for example, lightning__richtextType instead of lightning__richTextType) | Incorrect generated type name | Cross-check all lightning:type values against supported type names and correct them before deployment |
| Array property rejected | Use of items (or lightning:type in nested arrays) rejected by validator | For nested arrays: keep only type: "array". For root arrays: use minimal structure; remove items if rejected |
| Apex-based CLT rejected | Extra fields added (e.g., type, properties) | Use only title, optional description, and lightning:type |
| Editor config rejected | Use of invalid patterns (es_property_editors/inputList, itemSchema) or unrecognized top-level keys | Use editor.componentOverrides and editor.layout; keep config minimal |
additionalProperties error on layout attributes | Adding label or other attributes to lightning/propertyLayout | Only use property attribute in lightning/propertyLayout. Remove label, title, or any other attributes |
| Invalid target configuration for custom LWC | Custom LWC component's -meta.xml missing required target (lightning__AgentforceInput or lightning__AgentforceOutput) | Add correct target to LWC's -meta.xml: use lightning__AgentforceInput for editors, lightning__AgentforceOutput for renderers |
| Attribute mapping doesn't exist in type schema | Using {!$attrs.propertyName} where propertyName is not defined in schema | Ensure all attribute mappings reference actual properties in your type schema's properties section |
unevaluatedProperties error on custom LWC renderer for an Apex class CLT | Root override attributes mapping used on an Apex class CLT, which has no properties block to validate against | Remove attributes entirely from the root override; use "componentOverrides": { "$": { "definition": "c/<component>" } } only |
additionalProperties error with deprecated keys | Using propertyRenderers or view in editor/renderer config | Replace deprecated propertyRenderers with componentOverrides and view with layout |
| Type mismatch in component attributes | Passing wrong type for component attribute (e.g., integer instead of string) | Ensure attribute values match the expected type defined by the component |
type: "object", title, lightning:type: "lightning__objectType", and unevaluatedProperties: falseexamples when strict validation is enabledlightning:type: "lightning__objectType"lightning:type identifiers are used for leaf propertiestitle/description and lightning:type: "@apexClassType/..."es_property_editors/inputList, no itemSchema); use valid components (e.g. es_property_editors/inputText, es_property_editors/inputNumber) or custom c/ componentses_property_editors/outputText, es_property_editors/outputNumber) where applicable, not input editorslightning/propertyLayout with ONLY the property attribute (no label, title, or other attributes){!$attrs.propertyName}) reference properties that exist in the type schema-meta.xml: lightning__AgentforceInput for editors, lightning__AgentforceOutput for renderers"$schema" field