treeMerge Transform
Strict deep merge that errors on type conflicts. Use this when you want to catch configuration mistakes early.
Usage
Using in-memory data (recommended):
node:
base:
from_file: base.json
override:
from_file: override.json
config:
to_file: config.json
transform:
treeMerge:
- "{{.base}}"
- "{{.override}}"
Using file paths (via .meta):
node:
base:
from_file: base.json
override:
from_file: override.json
config:
to_file: config.json
transform:
treeMerge:
- "{{.meta.base.path}}"
- "{{.meta.override.path}}"
Behavior
| Scenario |
Result |
| Objects |
Keys are merged recursively |
| Arrays |
Later array replaces earlier array |
| Scalars |
Later value replaces earlier value |
| Type conflicts |
Error with detailed message |
Type Conflict Detection
treeMerge will error when types don't match:
base.json:
{
"settings": {
"debug": "false"
}
}
override.json:
{
"settings": {
"debug": true
}
}
Error:
type conflict at 'settings.debug': cannot merge string with bool
This catches common mistakes like:
- String
"false" vs boolean false
- Number
8080 vs string "8080"
- Scalar vs object/array
- Object vs array
Examples
Basic Merge (No Conflicts)
base.yaml:
name: app
database:
host: localhost
override.yaml:
database:
port: 5432
ssl: true
Result:
name: app
database:
host: localhost
port: 5432
ssl: true
Type Conflict Error
base.json:
override.json:
{"value": {"nested": "object"}}
Error:
node 'config': type conflict at 'value': cannot merge string with map
Multiple Files
transform:
treeMerge:
- "{{.schema}}"
- "{{.defaults}}"
- "{{.environment}}"
All inputs must have compatible types at each path.
CLI Usage
Run treeMerge directly from the command line:
panconf transform treeMerge base.json override.yaml
Output is YAML to stdout. Exits with error if type conflicts are detected.
Error Messages
treeMerge provides detailed error messages showing:
- The path where the conflict occurred (e.g.,
settings.database.port)
- The conflicting types