Skip to content

Fix optional query/header parameters with constant values being hardcoded#3812

Open
Copilot wants to merge 6 commits intomainfrom
copilot/fix-hardcoded-query-parameters
Open

Fix optional query/header parameters with constant values being hardcoded#3812
Copilot wants to merge 6 commits intomainfrom
copilot/fix-hardcoded-query-parameters

Conversation

Copy link
Contributor

Copilot AI commented Mar 4, 2026

getParameterMap in the modular emitter unconditionally hardcoded constant-type parameters, ignoring optionality. This meant optional params like @query("name") foo?: "literal" or @header("name") bar?: "literal" always emitted the literal value instead of reading from options, making them impossible to omit.

Changes

  • operationHelpers.ts: Gate the constant-value early return on !isOptional(param) so optional constants flow through the standard getOptional path, which reads from the options bag and preserves undefined for URL template omission and header conditional spreading.
- if (isConstant(param.type)) {
+ if (isConstant(param.type) && !isOptional(param)) {

Before (generated):

"optional%2Dquery%2Dname": "optionalQuery",  // always sent

After (generated):

"optional%2Dquery%2Dname": !options?.optionalQueryName
  ? options?.optionalQueryName
  : "optionalQuery",  // omitted when undefined
  • New test scenarios covering optional constant parameters across all parameter kinds:
    1. queryParam/optionalConstantQueryParam.md — Optional constant query parameters with path and body params
    2. headerParam/optionalConstantHeaderParam.md — Required constant, optional constant, and optional string header parameters with body
    3. bodyParam/optionalConstantBodyParam.md — Optional constant body parameter
Original prompt

This section details on the original issue you should resolve

<issue_title>[Modular] Optional query parameters with constant values should not be hardcoded</issue_title>
<issue_description>### Problem
When generating operations with optional query parameters that have constant literal types, the generated code hardcodes the constant values instead of reading them from the options. This prevents users from omitting these optional parameters.

Reproduction

TypeSpec

op read(@path pathParam: string,
    @path("path-name") pathName: "path",
    @path("optional-path-name") optionalPathName?: "optionalPath",
    @query("query-name") queryName: "query",
    @query("optional-query-name") optionalQueryName?: "optionalQuery",
    @query("key-version") keyVersion?: string,
    @body parameters: string): OkResponse;

Generated Code (Incorrect)

export function _readSend(
  context: Client,
  pathParam: string,
  parameters: string,
  options: ReadOptionalParams = { requestOptions: {} },
): StreamableMethod {
  const path = expandUrlTemplate(
    "/{pathParam}/{path-name}{/optional-path-name}{?query%2Dname,optional%2Dquery%2Dname,key%2Dversion}",
    {
      pathParam: pathParam,
      "path-name": "path",
      "optional-path-name": "optionalPath",  // Seems correct because path should not be optional?
      "query%2Dname": "query",
      "optional%2Dquery%2Dname": "optionalQuery",   // ❌ HARDCODED
      "key%2Dversion": options?.keyVersion,  // ✅ CORRECT: Uses options
    },
    {
      allowReserved: options?.requestOptions?.skipUrlEncoding,
    },
  );
  // ...
}
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Optional query parameters with constant literal types were being
hardcoded instead of reading from options. This prevented users from
omitting these optional parameters.

The fix checks if a constant parameter is also optional before
hardcoding its value. Optional constants now flow through the
standard optional parameter handling path, which reads from
options and allows the parameter to be omitted.

Co-authored-by: JialinHuang803 <139532647+JialinHuang803@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix hardcoded constant values in optional query parameters Fix optional query parameters with constant values being hardcoded Mar 4, 2026
@JialinHuang803
Copy link
Member

@copilot Update the unit test to cover header and body parameters.

Extended the unit test to cover three scenarios:
1. Optional constant query params with body
2. Optional constant header params (required + optional) with body
3. Combined optional constant query + header params with body

Co-authored-by: JialinHuang803 <139532647+JialinHuang803@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 5, 2026

@copilot Update the unit test to cover header and body parameters.

Added two more test scenarios in commit 73cacc7:

  1. Optional constant header parameters — covers required constant ("requiredValue"), optional constant ("optionalValue"), and optional string header types, all alongside a @body parameter
  2. Combined optional constant query + header with body — tests both @query and @header optional constants together with @body in a single operation

All 538 modular unit tests pass.

Copilot AI changed the title Fix optional query parameters with constant values being hardcoded Fix optional query/header parameters with constant values being hardcoded Mar 5, 2026
@JialinHuang803
Copy link
Member

@copilot the test is in the queryParam folder, while it contains header param test scenarios. Can you remove the test "Required constant body with optional constant query and header" and move to header test scenario to a correct place? Also add a test for optional constant body parameter.

- Remove combined query+header test and header test from queryParam/optionalConstantQueryParam.md
- Move optional constant header test to headerParam/optionalConstantHeaderParam.md
- Add optional constant body parameter test in bodyParam/optionalConstantBodyParam.md

Co-authored-by: JialinHuang803 <139532647+JialinHuang803@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 10, 2026

@copilot the test is in the queryParam folder, while it contains header param test scenarios. Can you remove the test "Required constant body with optional constant query and header" a...

Done in ba603b4:

  1. Removed the "Required constant body with optional constant query and header" combined test from queryParam/
  2. Moved the header test to headerParam/optionalConstantHeaderParam.md
  3. Added optional constant body parameter test at bodyParam/optionalConstantBodyParam.md

All 538 modular + 309 RLC unit tests pass.

@JialinHuang803 JialinHuang803 marked this pull request as ready for review March 10, 2026 03:55
Copy link
Member

@MaryGao MaryGao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved and left small comments.

@JialinHuang803 JialinHuang803 enabled auto-merge (squash) March 17, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Modular] Optional query parameters with constant values should not be hardcoded

3 participants