microsoft/aspire · error
aspire: merge type mismatch: cannot merge
Error message
aspire: merge type mismatch: cannot merge %v into %v
What it means
deepUpdate is a generic merge helper used by generated mergeable methods (WithMergeLogging, AddTestRedis, etc.). It panics when the source and destination values have different reflect.TypeOf because merging mismatched types would be meaningless. Since it panics rather than returns an error, callers must ensure type compatibility before invoking merge-style APIs.
Solutions
- Pass a value whose concrete type exactly matches the target (same struct type, same pointer-ness)
- Dereference or take the address of the argument to match the expected form before merging
- Ensure you are calling the intended merge overload for the type you have
Example fix
// before
opts := Options{A: 1}
deepUpdate(existingPtr, opts) // mismatch: *Options vs Options
// after
deepUpdate(existingPtr, &opts) Defensive patterns
Strategy: type-guard
Validate before calling
if reflect.TypeOf(src) != reflect.TypeOf(dst) {
return errors.New("cannot merge: source and destination types differ")
} Type guard
func sameConcreteType(a, b any) bool { return reflect.TypeOf(a) == reflect.TypeOf(b) } Try / catch
defer func() {
if r := recover(); r != nil {
return fmt.Errorf("merge failed: %v", r)
}
}() Prevention
- Match pointer-ness exactly when passing merge arguments
- Merge the same options struct type that was originally set
- Add a unit test exercising merge-style methods with your option types
When it happens
Trigger: Calling a merge-style generated method (e.g. WithMergeLogging/WithOptionalString/AddTestRedis) with a value whose concrete type differs from the existing/target value's type — e.g. merging *Config into Config, or a different struct type into an existing one.
Common situations: Passing a value type where a pointer is expected (or vice versa), passing a different options struct than the one originally set, or misuse of the generated deepUpdate in custom code.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- aspire: merge error
- argument ' ' passed to capability ' ' contains a circular…
- aspire: dict getter returned unexpected type %T
- aspire: dict.toObject: unexpected result type %T
- aspire: list getter returned unexpected type %T
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/b0b50015f23bd9c8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go:848
}
return structValue.Interface().(T), true
}
// ── deepUpdate ───────────────────────────────────────────────────────────────
//
// Used by generated code to merge variadic Options structs:
//
// merged := &AddRedisOptions{}
// for _, opt := range options {
// if opt != nil { merged = deepUpdate(merged, opt) }
// }
func deepUpdate[T any](dst, src T) T {
dstType := reflect.TypeOf(dst)
srcType := reflect.TypeOf(src)
if dstType != srcType {
panic(fmt.Sprintf("aspire: merge type mismatch: cannot merge %v into %v", srcType, dstType))
}
var nilT T
if reflect.DeepEqual(src, nilT) {
return dst
}
if reflect.DeepEqual(dst, nilT) {
return src
}
v := reflect.ValueOf(dst)
kind := v.Kind()
if kind == reflect.Ptr {
kind = v.Elem().Kind()
}
switch kind {
case reflect.Map, reflect.Struct:View on GitHub (pinned to 25830f84bd)