{"record":{"id":"f0ff304f2dc7d7e8","repo":"microsoft/aspire","slug":"getvalue-is-only-available-on-server-returned-base","errorCode":null,"errorMessage":"getValue is only available on server-returned ReferenceExpression instances","messagePattern":"getValue is only available on server-returned ReferenceExpression instances","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts","lineNumber":153,"sourceCode":"            $expr: {\n                format: state.format!,\n                valueProviders: state.valueProviders && state.valueProviders.length > 0 ? state.valueProviders : undefined\n            }\n        };\n    }\n\n    /**\n     * Resolves the expression to its string value on the server.\n     * Only available on server-returned ReferenceExpression instances (handle mode).\n     *\n     * @param cancellationToken - Optional AbortSignal or CancellationToken for cancellation support\n     * @returns The resolved string value, or null if the expression resolves to null\n     */\n    async getValue(cancellationToken?: AbortSignal | CancellationToken): Promise<string | null> {\n        const state = referenceExpressionState.get(this)!;\n\n        if (!state.handle || !state.client) {\n            throw new Error('getValue is only available on server-returned ReferenceExpression instances');\n        }\n        const cancellationTokenId = registerCancellation(state.client, cancellationToken);\n        try {\n            const rpcArgs: Record<string, unknown> = { context: state.handle };\n            if (cancellationTokenId !== undefined) rpcArgs.cancellationToken = cancellationTokenId;\n            return await state.client.invokeCapability<string | null>(\n                'Aspire.Hosting.ApplicationModel/getValue',\n                rpcArgs\n            );\n        } finally {\n            unregisterCancellation(cancellationTokenId);\n        }\n    }\n\n    /**\n     * String representation for debugging.\n     */\n    toString(): string {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts#L135-L171","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst expr = new ReferenceExpression(parts);\nconst v = await expr.getValue();   // throws: only server-returned instances supported\n\n// after\nconst v = await serverReturnedExpression.getValue();  // expression obtained from the AppHost/resource model","handlingStrategy":"type-guard","validationCode":"// only resolve expressions that came from the server model\nfunction isServerReturnedExpression(expr) {\n  return expr != null && typeof expr.getValue === 'function' && expr.__serverReturned === true;\n}","typeGuard":"function canResolve(expr) { return expr != null && typeof expr?.getValue === 'function' && expr['__handle'] != null; }","tryCatchPattern":"try {\n  const value = await expr.getValue();\n} catch (err) {\n  if (err instanceof Error && err.message.includes('server-returned ReferenceExpression')) {\n    // use a server-provided expression or a literal value instead\n  }\n}","preventionTips":["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."],"tags":["typescript","reference-expression","rpc","misuse"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}