microsoft/aspire · error · Error
Cannot use null or undefined in reference expression
Error message
Cannot use null or undefined in reference expression
What it means
The generated TypeScript runtime's internal extractHandleForExpr builds reference expressions from handles (server objects) and string literals only. Passing null or undefined is ambiguous — the runtime cannot represent either in a reference expression — so it throws this Error up front instead of producing a malformed expression that would fail on the server side.
Solutions
- Check the value for null/undefined before passing it into the reference-expression helper, and substitute a string literal or a valid handle.
- Trace where the undefined came from — a failed lookup or optional property — and fix the source (provide a default, fix the key, or await an async lookup).
- If the value is legitimately optional, branch your code: build the expression only when the value exists, otherwise use a fallback string or skip the reference.
- Add TypeScript strict null checks (strictNullChecks) so the compiler flags possibly-undefined values before they reach the helper.
Example fix
// before const endpoint = process.env.MAYBE_ENDPOINT; const expr = value(endpoint); // throws when undefined // after const endpoint = process.env.MAYBE_ENDPOINT ?? 'http://localhost:8080'; const expr = value(endpoint);
Defensive patterns
Strategy: validation
Validate before calling
function assertExprInput(v) {
if (v === null || v === undefined) throw new TypeError('Reference expression value must be a handle or string, got ' + v);
return v;
}
// call assertExprInput(x) before value(x) Type guard
function isExprValue(v) { return typeof v === 'string' || (v !== null && v !== undefined && typeof v === 'object'); } Try / catch
try {
const expr = value(input);
} catch (err) {
if (err instanceof Error && err.message.includes('null or undefined')) {
// fall back to a default literal or skip building the expression
}
} Prevention
- Enable strictNullChecks so possibly-undefined values are caught at compile time.
- Provide defaults for optional lookups (`?? fallback`) before building expressions.
- Avoid optional chaining that can silently pass undefined into expression helpers.
When it happens
Trigger: Calling a reference-expression building API (e.g. the `value`/expression helpers that call extractHandleForExpr) with null or undefined as the value — commonly from an unset variable, an optional field, or a failed lookup like env.get(...)/map lookup returning undefined.
Common situations: Optional endpoint or parameter lookups that return undefined at runtime; TypeScript optional chaining (`resource?.endpoint`) silently yielding undefined; object destructuring where the property does not exist; passing a variable before it is assigned.
Related errors
- Cannot use None in reference expression
- Argument ' ' passed to capability ' ' is a Promise-like…
- Cannot use value of type
- Cannot use value of type
- getValue is only available on server-returned…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/642d09ee859e4a60.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts:261
if (typeof matchValueOrWhenTrue === 'string') {
return new ReferenceExpression(condition, matchValueOrWhenTrue, whenTrueOrWhenFalse, whenFalse!);
}
return new ReferenceExpression(condition, 'True', matchValueOrWhenTrue, whenTrueOrWhenFalse);
}
registerHandleWrapper('Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression', (handle, client) =>
new ReferenceExpression(handle, client)
);
/**
* Extracts a value for use in reference expressions.
* Supports handles (objects) and string literals.
* @internal
*/
function extractHandleForExpr(value: unknown): unknown {
if (value === null || value === undefined) {
throw new Error('Cannot use null or undefined in reference expression');
}
// String literals - include directly in the expression
if (typeof value === 'string') {
return value;
}
// Number literals - convert to string
if (typeof value === 'number') {
return String(value);
}
// Handle objects - get their JSON representation
if (isHandleLike(value)) {
return value.toJSON();
}
// Objects with marshalled expression/handle payloadsView on GitHub (pinned to 25830f84bd)