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

  1. 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).
  2. For values known at build time, use the literal directly instead of wrapping it in a ReferenceExpression and resolving it.
  3. 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.
  4. 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

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


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)