For data model object (DMO)-to-DMO transforms (transforms that read from and write to DMOs), don’t use the sf data-code-extension script scan command because you must pass the DMO schema. Instead, follow the schema standards to configure the config.json file manually.
Schema Structure Overview
This schema example demonstrates the structure of a config.json file for DMO-to-DMO transforms:
Use different object names for read and write operations.
Every DMO in the write list must have a corresponding schema definition in dataObjects. You don’t have to define schemas for DMOs in the read list.
dataObjects Schema
The dataObjects array contains schema definitions for each output DMO that your script writes to. Each object in the array defines the complete structure of a DMO, including its fields, data types, and primary keys.
Object-Level Schema
Each object in the dataObjects array represents one DMO and must include these properties.
Property
Required
Type
Description
name
Yes
String
DMO name. Must match a name in permissions.write.dmo.
category
Yes
String
Set to “profile”, “engagement”, or “other” (case-insensitive).
fields
Yes
Array
Array of field definitions. Include at least one field.
timeEventField
Conditional
String
Required when category is “engagement”. Name of a dateTime field defined in fields that holds the event time.
label
No
String
Human-readable label.
type
No
String
The object type for the schema entry. Set to “dataModelObject” for DMOs.
description
No
String
Description of the DMO.
Supported DMO Categories
You can write to DMOs in any of these categories.
profile - Profile data, such as accounts or contacts.
engagement - Time-series engagement data, such as events or interactions. An engagement DMO must include a timeEventField at the object level that names a dateTime field in fields.
other - Data that doesn’t fit the profile or engagement categories.
For an engagement DMO, supply the timeEventField property at the object level and define the referenced field as a dateTime field in the fields array.
If your script writes to multiple DMOs, define a schema for each one in the dataObjects array. Each DMO must have its own object definition with a complete field schema.
Your config.json file must meet these validation requirements.
Configuration Level
Read and write permissions must not be empty.
Dataspace must not be blank.
Don’t read and write the same object.
Schema Level
dataObjects must be present and not empty.
Every DMO in permissions.write.dmo must have a matching schema in dataObjects.
Each object’s name must not be blank.
Each object’s category must be “profile”, “engagement”, or “other”.
Each object with the “engagement” category must include a timeEventField that names a dateTime field defined in fields.
Each object must have at least one field.
Field Level
Each field’s name must not be blank.
Each field’s dataType must not be blank.
isPrimaryKey must be specified for each field.
Troubleshoot Common Errors
These errors occur during package validation when your config.json doesn’t follow the required schema standards.
Error Message
Solution
No DMO schema found
Add dataObjects array with schemas for all write DMOs
Some DMO write targets do not have a schema
Ensure all DMO names in write.dmo have matching entries in dataObjects
Invalid DMO Schema: name missing
Add name property to data object
Invalid DMO Schema: invalid object category
Set category to “profile”, “engagement”, or “other”
Invalid DMO fields schema
Ensure all fields have name and dataType
Can’t read and write from/to the same entity
Use different DMO names for read vs write
Currently, all these validation errors surface to the Connect API as error code 2999 (“Unknown error occurred”). The preceding error messages are available in the logs for debugging.
Note
Best Practices
Start with write targets: List all DMOs you write to in permissions.write.dmo.
Create matching schemas: Make sure that each DMO has a corresponding entry in dataObjects with the same name.
Define all output fields: Include all fields that your script writes.
Set primary keys correctly: Identify primary keys and mark them with isPrimaryKey: true.
Match your script output: Ensure field names match what your Python script produces.
Use descriptive labels: While optional, labels improve readability and debugging.