Skip to content

Remove unreachable null check from toQueryParams fallthrough case#306

Merged
sergey-tihon merged 2 commits intorepo-assist/improve-runtime-helpers-tests-2026-03-4685f59d81f67329from
copilot/sub-pr-295
Mar 10, 2026
Merged

Remove unreachable null check from toQueryParams fallthrough case#306
sergey-tihon merged 2 commits intorepo-assist/improve-runtime-helpers-tests-2026-03-4685f59d81f67329from
copilot/sub-pr-295

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 10, 2026

The _ catch-all in toQueryParams contained a dead null branch that could never execute, due to a misunderstanding of how F# routes null through pattern matching.

Root cause

F# treats null as None for reference-type options at the .NET level (e.g., box (Option<string>.None) = null). When pattern matching against obj, F# binds null to the first matching | :? Option<T> as x -> arm — so null is correctly handled as None and returns [] via toStrOpt, never reaching _.

The original _ case:

| _ -> [ name, (if isNull obj then null else obj.ToString()) ]

...had a null branch returning [ (name, null) ] that was unreachable. Adding an explicit | null -> pattern after the option arms would produce compiler warning FS0026: This rule will never be matched.

Change

Simplified the fallthrough to remove the dead null check:

| _ -> [ name, obj.ToString() ]

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix feedback on unit tests for RuntimeHelpers module Remove unreachable null check from toQueryParams fallthrough case Mar 10, 2026
@sergey-tihon sergey-tihon marked this pull request as ready for review March 10, 2026 21:53
Copilot AI review requested due to automatic review settings March 10, 2026 21:53
@sergey-tihon sergey-tihon merged commit 5aecbda into repo-assist/improve-runtime-helpers-tests-2026-03-4685f59d81f67329 Mar 10, 2026
15 checks passed
@sergey-tihon sergey-tihon deleted the copilot/sub-pr-295 branch March 10, 2026 21:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR simplifies query-parameter serialization in RuntimeHelpers.toQueryParams by removing an unreachable null check from the catch-all pattern, based on how null is handled earlier in the match.

Changes:

  • Simplified the _ fallthrough case in toQueryParams to call obj.ToString() directly.
  • Removed the dead isNull obj branch that could not be executed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

sergey-tihon added a commit that referenced this pull request Mar 10, 2026
* Add unit tests for RuntimeHelpers module

RuntimeHelpers.fs handles all parameter serialization and HTTP request
building for generated API clients, but previously had zero dedicated
unit tests. This PR adds 44 focused tests covering:

- toParam: DateTime/DateTimeOffset ISO 8601 formatting, null handling
- toQueryParams: all supported array/option/scalar types, DateTime
  ISO 8601 serialization, None filtering in optional arrays
- combineUrl: trailing/leading slash normalisation
- createHttpRequest: HTTP method, path, query params, null filtering
- fillHeaders: header addition, null-value skip, Content-Type silence
- toStringContent/toTextContent/toStreamContent: content-type headers,
  error on non-stream input

Closes no specific issue; improves baseline test coverage for the
runtime serialization layer (Task 9 - Testing Improvements).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: trigger checks

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types (#304)

* Initial plan

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Merge master and fix CI: add RuntimeHelpers unit tests (#305)

* Fix Option types in form data not being unwrapped (issue #214) (#298)

RuntimeHelpers.getPropertyValues now strips the FSharpOption<T>
wrapper before returning property values. Previously, a property
set to Some(true) was serialised as the string "Some(true)" in
multipart/form-data and application/x-www-form-urlencoded bodies
instead of the bare "True". None values were already handled (null).

Also relax global.json SDK version constraint from 10.0.103 to
10.0.100 with rollForward:latestPatch so the project builds with
any 10.0.1xx SDK available locally or in CI.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Initial plan

* Fix Build and Test workflow to run on all pull requests, not just PRs targeting master

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Remove unreachable null check from `toQueryParams` fallthrough case (#306)

* Initial plan

* Fix toQueryParams: remove unreachable null check from _ case

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Make null handling explicit in `toQueryParams` and fix misleading test comment (#307)

* Initial plan

* Add explicit null guard in toQueryParams and fix test comment

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Apply Fantomas formatting to RuntimeHelpers.fs

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
sergey-tihon added a commit that referenced this pull request Mar 10, 2026
* Fix Option types in form data not being unwrapped (issue #214) (#298)

RuntimeHelpers.getPropertyValues now strips the FSharpOption<T>
wrapper before returning property values. Previously, a property
set to Some(true) was serialised as the string "Some(true)" in
multipart/form-data and application/x-www-form-urlencoded bodies
instead of the bare "True". None values were already handled (null).

Also relax global.json SDK version constraint from 10.0.103 to
10.0.100 with rollForward:latestPatch so the project builds with
any 10.0.1xx SDK available locally or in CI.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add concurrency group to CI workflow to cancel redundant builds (#309)

When multiple commits are pushed to the same PR branch, GitHub Actions
queues a new build for each push. Without a concurrency group, the older
builds keep running even though they're now stale.

Adding cancel-in-progress: true cancels the in-progress build when a
newer commit arrives on the same ref, reducing CI minutes consumed and
giving faster feedback on the latest commit.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [Repo Assist] Add unit tests for RuntimeHelpers module (#295)

* Add unit tests for RuntimeHelpers module

RuntimeHelpers.fs handles all parameter serialization and HTTP request
building for generated API clients, but previously had zero dedicated
unit tests. This PR adds 44 focused tests covering:

- toParam: DateTime/DateTimeOffset ISO 8601 formatting, null handling
- toQueryParams: all supported array/option/scalar types, DateTime
  ISO 8601 serialization, None filtering in optional arrays
- combineUrl: trailing/leading slash normalisation
- createHttpRequest: HTTP method, path, query params, null filtering
- fillHeaders: header addition, null-value skip, Content-Type silence
- toStringContent/toTextContent/toStreamContent: content-type headers,
  error on non-stream input

Closes no specific issue; improves baseline test coverage for the
runtime serialization layer (Task 9 - Testing Improvements).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: trigger checks

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types (#304)

* Initial plan

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Merge master and fix CI: add RuntimeHelpers unit tests (#305)

* Fix Option types in form data not being unwrapped (issue #214) (#298)

RuntimeHelpers.getPropertyValues now strips the FSharpOption<T>
wrapper before returning property values. Previously, a property
set to Some(true) was serialised as the string "Some(true)" in
multipart/form-data and application/x-www-form-urlencoded bodies
instead of the bare "True". None values were already handled (null).

Also relax global.json SDK version constraint from 10.0.103 to
10.0.100 with rollForward:latestPatch so the project builds with
any 10.0.1xx SDK available locally or in CI.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Initial plan

* Fix Build and Test workflow to run on all pull requests, not just PRs targeting master

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Remove unreachable null check from `toQueryParams` fallthrough case (#306)

* Initial plan

* Fix toQueryParams: remove unreachable null check from _ case

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Make null handling explicit in `toQueryParams` and fix misleading test comment (#307)

* Initial plan

* Add explicit null guard in toQueryParams and fix test comment

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Apply Fantomas formatting to RuntimeHelpers.fs

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
Co-authored-by: Don Syme <dsyme@users.noreply.github.com>

* Initial plan

---------

Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Sergey Tihon <sergey.tihon@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
sergey-tihon added a commit that referenced this pull request Mar 10, 2026
…eference (#310)

* Fix $0 in path parameter values treated as regex back-reference (#141)

Regex.Replace uses $0, $1, $& etc. as back-references in the replacement
string. When a path parameter value contained a literal dollar sign (e.g.
"$0something"), Regex.Replace would substitute it with the matched text
instead of the literal value.

Fix: escape $ characters in the replacement string by replacing "$" with
"$$" (the .NET replacement-string escape for a literal dollar sign).
This applies to both the v2 SwaggerClientProvider and v3 OpenApiClientProvider.

Also adds:
- EchoPathController in the test server that returns its string path parameter
- A regression test in SpecialCasesControllers.Tests.fs that passes "$0something"
  through a path parameter and asserts the value is echoed back unchanged
- global.json rollForward updated from minor/10.0.103 to latestPatch/10.0.100
  so the project builds with any 10.0.1xx SDK available in CI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix $ in path parameters treated as Regex.Replace back-references (#311)

* Fix Option types in form data not being unwrapped (issue #214) (#298)

RuntimeHelpers.getPropertyValues now strips the FSharpOption<T>
wrapper before returning property values. Previously, a property
set to Some(true) was serialised as the string "Some(true)" in
multipart/form-data and application/x-www-form-urlencoded bodies
instead of the bare "True". None values were already handled (null).

Also relax global.json SDK version constraint from 10.0.103 to
10.0.100 with rollForward:latestPatch so the project builds with
any 10.0.1xx SDK available locally or in CI.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add concurrency group to CI workflow to cancel redundant builds (#309)

When multiple commits are pushed to the same PR branch, GitHub Actions
queues a new build for each push. Without a concurrency group, the older
builds keep running even though they're now stale.

Adding cancel-in-progress: true cancels the in-progress build when a
newer commit arrives on the same ref, reducing CI minutes consumed and
giving faster feedback on the latest commit.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [Repo Assist] Add unit tests for RuntimeHelpers module (#295)

* Add unit tests for RuntimeHelpers module

RuntimeHelpers.fs handles all parameter serialization and HTTP request
building for generated API clients, but previously had zero dedicated
unit tests. This PR adds 44 focused tests covering:

- toParam: DateTime/DateTimeOffset ISO 8601 formatting, null handling
- toQueryParams: all supported array/option/scalar types, DateTime
  ISO 8601 serialization, None filtering in optional arrays
- combineUrl: trailing/leading slash normalisation
- createHttpRequest: HTTP method, path, query params, null filtering
- fillHeaders: header addition, null-value skip, Content-Type silence
- toStringContent/toTextContent/toStreamContent: content-type headers,
  error on non-stream input

Closes no specific issue; improves baseline test coverage for the
runtime serialization layer (Task 9 - Testing Improvements).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: trigger checks

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types (#304)

* Initial plan

* Add missing toQueryParams test cases: float32/double/byte arrays and Option array types

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Merge master and fix CI: add RuntimeHelpers unit tests (#305)

* Fix Option types in form data not being unwrapped (issue #214) (#298)

RuntimeHelpers.getPropertyValues now strips the FSharpOption<T>
wrapper before returning property values. Previously, a property
set to Some(true) was serialised as the string "Some(true)" in
multipart/form-data and application/x-www-form-urlencoded bodies
instead of the bare "True". None values were already handled (null).

Also relax global.json SDK version constraint from 10.0.103 to
10.0.100 with rollForward:latestPatch so the project builds with
any 10.0.1xx SDK available locally or in CI.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Initial plan

* Fix Build and Test workflow to run on all pull requests, not just PRs targeting master

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Remove unreachable null check from `toQueryParams` fallthrough case (#306)

* Initial plan

* Fix toQueryParams: remove unreachable null check from _ case

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Make null handling explicit in `toQueryParams` and fix misleading test comment (#307)

* Initial plan

* Add explicit null guard in toQueryParams and fix test comment

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

* Apply Fantomas formatting to RuntimeHelpers.fs

Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
Co-authored-by: Don Syme <dsyme@users.noreply.github.com>

* Initial plan

---------

Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Sergey Tihon <sergey.tihon@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

3 participants