microsoft/aspire · error · Error
getValue is only available on server-returned…
Error message
getValue is only available on server-returned ReferenceExpression instances
What it means
In the generated TypeScript runtime (base.mts), ReferenceExpression.getValue can only perform an RPC to resolve a value when the expression instance was created by the server and carries a server-side handle and RPC client. Locally constructed ReferenceExpression objects have no handle, so calling getValue throws this Error to signal that value resolution is not supported for them.
Solutions
- Only call getValue on ReferenceExpression instances returned by the server (e.g. from resource builders or references handed to you by the AppHost-generated model).
- For values known at build time, use the literal directly instead of wrapping it in a ReferenceExpression and resolving it.
- If you need a resolved string in generated code, obtain the value through the resource's built-in accessors (e.g. connectionString or endpoint URLs) rather than manual expression construction.
- Check that you are not accidentally shadowing/overwriting a server-returned expression with a locally created one before calling getValue.
Example fix
// before const expr = new ReferenceExpression(parts); const v = await expr.getValue(); // throws: only server-returned instances supported // after const v = await serverReturnedExpression.getValue(); // expression obtained from the AppHost/resource model
Defensive patterns
Strategy: type-guard
Validate before calling
// only resolve expressions that came from the server model
function isServerReturnedExpression(expr) {
return expr != null && typeof expr.getValue === 'function' && expr.__serverReturned === true;
} Type guard
function canResolve(expr) { return expr != null && typeof expr?.getValue === 'function' && expr['__handle'] != null; } Try / catch
try {
const value = await expr.getValue();
} catch (err) {
if (err instanceof Error && err.message.includes('server-returned ReferenceExpression')) {
// use a server-provided expression or a literal value instead
}
} Prevention
- Call getValue only on expressions returned by the AppHost/resource model.
- Never construct ReferenceExpression manually in generated client code.
- Prefer resource built-in accessors (connectionString, endpoint URLs) for resolved values.
When it happens
Trigger: Constructing a ReferenceExpression directly in generated/client code (e.g. `new ReferenceExpression(...)` or via the `value` helper path) and then calling `await expr.getValue()` instead of using a reference obtained from a resource (like a connection string or endpoint reference) returned by the AppHost.
Common situations: Trying to eagerly resolve a parameter/endpoint reference in client code before/without server involvement; writing custom expression-building code that mimics what the generator emits; using an older generated runtime where expressions were resolved differently.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot use null or undefined in reference expression
- Cannot use value of type
- result.$error
- -32000
- Already connected to AppHost backchannel.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/f0ff304f2dc7d7e8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts:153
$expr: {
format: state.format!,
valueProviders: state.valueProviders && state.valueProviders.length > 0 ? state.valueProviders : undefined
}
};
}
/**
* Resolves the expression to its string value on the server.
* Only available on server-returned ReferenceExpression instances (handle mode).
*
* @param cancellationToken - Optional AbortSignal or CancellationToken for cancellation support
* @returns The resolved string value, or null if the expression resolves to null
*/
async getValue(cancellationToken?: AbortSignal | CancellationToken): Promise<string | null> {
const state = referenceExpressionState.get(this)!;
if (!state.handle || !state.client) {
throw new Error('getValue is only available on server-returned ReferenceExpression instances');
}
const cancellationTokenId = registerCancellation(state.client, cancellationToken);
try {
const rpcArgs: Record<string, unknown> = { context: state.handle };
if (cancellationTokenId !== undefined) rpcArgs.cancellationToken = cancellationTokenId;
return await state.client.invokeCapability<string | null>(
'Aspire.Hosting.ApplicationModel/getValue',
rpcArgs
);
} finally {
unregisterCancellation(cancellationTokenId);
}
}
/**
* String representation for debugging.
*/
toString(): string {View on GitHub (pinned to 25830f84bd)