{"record":{"id":"c3701d7950ba275f","repo":"microsoft/aspire","slug":"aspire-dict-getter-q-returned-unexpected-type-t","errorCode":null,"errorMessage":"aspire: dict getter %q returned unexpected type %T","messagePattern":"aspire: dict getter %q returned unexpected type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go","lineNumber":434,"sourceCode":"\t}\n\td.handleMu.Lock()\n\tcached := d.resolvedHandle\n\td.handleMu.Unlock()\n\tif cached != nil {\n\t\treturn cached, nil\n\t}\n\tif d.getterCapabilityID == \"\" {\n\t\treturn d.parent.handle, nil\n\t}\n\tresult, err := d.parent.client.invokeCapability(ctx, d.getterCapabilityID, map[string]any{\n\t\t\"context\": d.parent.handle.ToJSON(),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\th, ok := result.(handleReference)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"aspire: dict getter %q returned unexpected type %T\", d.getterCapabilityID, result)\n\t}\n\tdictHandle := h.getHandle()\n\td.handleMu.Lock()\n\td.resolvedHandle = dictHandle\n\td.handleMu.Unlock()\n\treturn dictHandle, nil\n}\n\nfunc (d *Dict[K, V]) ToJSON() map[string]any {\n\th, err := d.resolveDictHandle(context.Background())\n\tif err != nil || h == nil {\n\t\treturn nil\n\t}\n\tout := h.ToJSON()\n\treturn map[string]any{\"$handle\": out[\"$handle\"], \"$type\": out[\"$type\"]}\n}\n\nfunc (d *Dict[K, V]) Count() (int, error) {","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go#L416-L452","documentation":"resolveDictHandle calls the dict's getter capability over the AppHost transport and requires the result to be a handleReference. Any other returned type breaks the handle-resolution contract and triggers this error, which includes the capability ID and the offending Go type.","triggerScenarios":"Performing any dictionary operation that first resolves the handle when the getter returns a non-handleReference payload — contract mismatch between the generated dict wrapper and the AppHost responder.","commonSituations":"Stale generated code vs newer AppHost, a getter capability implemented incorrectly (returns value map instead of handle), or transport deserialization producing a different concrete type than expected.","solutions":["Regenerate Go resource bindings to match the current AppHost protocol version.","Inspect the reported %T in the message to identify what the transport actually returned.","Confirm no custom code replaces or intercepts the dict getter capability.","Align aspire Go package and AppHost versions."],"exampleFix":"// before\ndictHandle, err := d.resolveDictHandle(ctx)\n// after\nresult, err := invokeGetter(ctx, d.getterCapabilityID)\nif err != nil { return err }\nh, ok := result.(handleReference)\nif !ok {\n    return fmt.Errorf(\"dict getter %q: got %T; regenerate bindings (expected handleReference)\", d.getterCapabilityID, result)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isHandleReference(v any) bool { _, ok := v.(handleReference); return ok }","tryCatchPattern":"v, err := dict.Get(ctx, key)\nif err != nil {\n    return fmt.Errorf(\"dict handle resolution failed: %w\", err)\n}","preventionTips":["Regenerate bindings after protocol changes.","Version-align generated code with AppHost.","Avoid custom interceptors on dict getters."],"tags":["go","aspire","internal-error","protocol","type-mismatch"],"backgroundTag":"internal-invariant-violation","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"}