{"record":{"id":"85e75ed6e23f73a4","repo":"microsoft/aspire","slug":"aspire-dict-toobject-unexpected-result-type-t","errorCode":null,"errorMessage":"aspire: dict.toObject: unexpected result type %T","messagePattern":"aspire: dict\\.toObject: unexpected result type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go","lineNumber":574,"sourceCode":"\t}\n\treturn vals, nil\n}\n\nfunc (d *Dict[K, V]) ToObject() (map[string]V, error) {\n\tctx := context.Background()\n\th, err := d.resolveDictHandle(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresult, err := d.parent.client.invokeCapability(ctx, \"Aspire.Hosting/Dict.toObject\", map[string]any{\n\t\t\"dict\": h.ToJSON(),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tm, ok := result.(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"aspire: dict.toObject: unexpected result type %T\", result)\n\t}\n\tobj := make(map[string]V, len(m))\n\tfor k, raw := range m {\n\t\tv, err := decodeAs[V](raw)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tobj[k] = v\n\t}\n\treturn obj, nil\n}\n\nfunc (d *Dict[K, V]) Set(key K, value V) error {\n\tctx := context.Background()\n\th, err := d.resolveDictHandle(ctx)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go#L556-L592","documentation":"Dict.ToObject invokes the getter capability and expects a map[string]any snapshot of the dictionary. If the transport returns another type (e.g. a handle reference instead of a full value snapshot), ToObject fails with this message including the actual type.","triggerScenarios":"Calling ToObject on an AspireDictValue when the AppHost responds with a non-map payload — usually when the getter resolves to a handle rather than materializing values, or the response shape changed between versions.","commonSituations":"Version drift between generated Go code and AppHost, custom getter returning nested/handle results, transport layer mapping the response to an unexpected concrete type.","solutions":["Regenerate the Go resource bindings to match the running AppHost.","Log the actual result type from the error message and compare with the documented response shape for toObject.","Ensure the dict is materializable (not a lazy handle-only reference) before calling ToObject.","Upgrade/downgrade the aspire Go package so both sides share the same protocol."],"exampleFix":"// before\nm, ok := result.(map[string]any)\nif !ok {\n    return nil, fmt.Errorf(\"aspire: dict.toObject: unexpected result type %T\", result)\n}\n// after\nresult, err := invokeGetter(ctx, d.getterCapabilityID)\nif err != nil { return err }\nif h, isHandle := result.(handleReference); isHandle {\n    return nil, fmt.Errorf(\"dict is a lazy handle (%s); call Get per key instead of ToObject\", h.id)\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asValueMap(v any) (map[string]any, bool) { m, ok := v.(map[string]any); return m, ok }","tryCatchPattern":"obj, err := dict.ToObject(ctx)\nif err != nil {\n    // fall back to per-key access\n    v, getErr := dict.Get(ctx, \"key\")\n    if getErr != nil { return getErr }\n    _ = v\n}","preventionTips":["Regenerate generated code when upgrading the AppHost.","Check the actual type in the message before assuming data corruption.","Use per-key Get for lazy/handle-backed dicts instead of ToObject."],"tags":["go","aspire","type-mismatch","protocol"],"backgroundTag":"unexpected-response-shape","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}