microsoft/aspire · error
aspire: GetValue is only available on server-returned…
Error message
aspire: GetValue is only available on server-returned ReferenceExpression instances
What it means
In the Go client, ReferenceExpression.GetValue only works when the expression came from the server and carries a handle and client. Locally constructed ReferenceExpression values (parsed inline, returned by non-server APIs) have no handle, so GetValue returns the error "aspire: GetValue is only available on server-returned ReferenceExpression instances".
Solutions
- Obtain the ReferenceExpression from a server-returned API/capability call so handle and client are populated.
- For local expressions, resolve/format the value client-side instead of calling GetValue.
- Ensure the client connection used to produce the expression is still alive and associated with it.
Example fix
// before
expr := &ReferenceExpression{Value: cs}
s, err := expr.GetValue(ctx)
// after
expr := server.GetConnectionString(ctx) // server-returned, has handle+client
s, err := expr.GetValue(ctx) Defensive patterns
Strategy: validation
Validate before calling
if expr == nil || !expr.HasHandle() { // or check expr.handle/client per API
return fmt.Errorf("expression is not server-returned; GetValue unavailable")
} Type guard
func isServerReturned(expr *ReferenceExpression) bool {
return expr != nil && expr.handle != nil && expr.client != nil
} Try / catch
s, err := expr.GetValue(ctx)
if err != nil && strings.Contains(err.Error(), "only available on server-returned") {
s = expr.FormatClientSide() // local fallback
} Prevention
- Only call GetValue on expressions returned by server capability calls.
- Resolve locally-built expressions client-side.
- Keep the originating client connection alive for the lifetime of the expression.
When it happens
Trigger: Calling GetValue on a ReferenceExpression created locally (e.g. via a constructor/parser or a client-side helper) instead of one returned by a server call that attaches handle and client.
Common situations: Hand-building a ReferenceExpression from a string in tests or glue code; caching an expression then losing its client association after reconnect; mixing client-side formatting with server-side resolution.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- -32000
- argument ' ' passed to capability ' ' contains a circular…
- aspire: build returned unexpected type %T
- aspire: returned unexpected type %T
- aspire: createBuilder returned unexpected type %T
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/1239eed3438023bb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.Go/Resources/base.go:203
"whenTrue": r.WhenTrue.ToJSON(),
"whenFalse": r.WhenFalse.ToJSON(),
"matchValue": r.MatchValue,
},
}
}
return map[string]any{
"$expr": map[string]any{
"format": r.Format,
"valueProviders": r.ValueProviders,
},
}
}
// GetValue resolves the expression to its string value on the server.
// Only available on server-returned ReferenceExpression instances (handle mode).
func (r *ReferenceExpression) GetValue(token *CancellationToken) (string, error) {
if r.handle == nil || r.client == nil {
return "", errors.New("aspire: GetValue is only available on server-returned ReferenceExpression instances")
}
args := map[string]any{
"context": r.handle.ToJSON(),
}
ctx := context.Background()
if token != nil {
ctx = token.Context()
if id := r.client.registerCancellation(token); id != "" {
args["cancellationToken"] = id
}
}
result, err := r.client.invokeCapability(ctx, "Aspire.Hosting.ApplicationModel/getValue", args)
if err != nil {
return "", err
}
if s, ok := result.(string); ok {View on GitHub (pinned to 25830f84bd)