Skip to content

Add top-level validate command. Closes #2055 - #2111

Open
waldekmastykarz wants to merge 5 commits into
dotnet:mainfrom
waldekmastykarz:validate-command
Open

waldekmastykarz wants to merge 5 commits into
dotnet:mainfrom
waldekmastykarz:validate-command

Conversation

@waldekmastykarz

Copy link
Copy Markdown
Collaborator

Closes #2055

What

Adds a top-level devproxy validate command so developers and agents can check a Dev Proxy config without starting the proxy. It shares its implementation with the existing devproxy config validate and supports -c/--config-file and --output json. Exit code is 0 when the config is valid and 2 when it's invalid.

The PR also extends validation to mirror the checks Dev Proxy runs at startup:

  • Plugin config sections are validated against their schemas. A section is checked only when it declares a $schema and validateSchemas isn't false. Errors are reported with the section name as the path.
  • Schema version mismatches in plugin sections produce a warning.
  • Plugins with no URLs to watch produce a warning. These plugins have no plugin-level or global urlsToWatch, so the proxy won't load them.
  • A configSection that's referenced but missing produces a warning, because the plugin falls back to its defaults.

Design notes

  • Missing URLs and missing config sections are reported as warnings, not errors. At runtime, --urls-to-watch or stdio mode can supply URLs, and a missing section isn't fatal, so marking the config as invalid would cause false negatives.
  • validate goes through the same early standalone path as config validate in Program.cs, so it doesn't load plugins or start the proxy.

Tests

  • Added ConfigValidateTests, which covers plugin URL warnings, missing sections, schema errors in sections, and the validateSchemas: false opt-out. It uses a fake schema handler, so the tests don't hit the network.
  • The full solution builds, and all tests pass.

Adds 'devproxy validate' as a top-level alias for 'devproxy config validate'
and extends validation to check plugin config sections against their schemas,
warn about plugins without URLs to watch, and warn about missing config sections.

Closes dotnet#2055

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@waldekmastykarz
waldekmastykarz requested a review from a team as a code owner November 13, 2026 11:54
Copilot AI balanced review requested due to automatic review settings November 13, 2026 11:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Validation mishandles CLI arguments and help, can crash on unexpected JSON types, emits an incompatible JSON envelope, and can skip plugin schema validation for valid section paths.

4 open issues
What changed in this PR

Adds devproxy validate as a standalone shortcut to config validate, addressing #2055 so developers and agents can check configurations without starting the proxy.

Changes:

  • Registers the top-level command with config-file selection and JSON output support.
  • Extends shared validation with plugin-section schema checks and warnings for missing URLs, missing sections, and schema-version mismatches.
  • Adds focused validation tests using a fake HTTP handler.
File Description
DevProxy/​Program.cs Updates the comment describing early standalone validation.
DevProxy/​Commands/​ValidateCommand.cs Adds the top-level command and usage examples.
DevProxy/​Commands/​DevProxyCommand.cs Registers validate and recognizes it for standalone routing.
DevProxy/​Commands/​ConfigCommand.cs Shares validation helpers and adds plugin-setting checks.
DevProxy.Tests/​ConfigValidateTests.cs Tests plugin warnings, schema errors, and schema-validation opt-out.

Review effort: Balanced

Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Comment thread DevProxy/Commands/DevProxyCommand.cs Resolved
Comment thread DevProxy/Commands/ValidateCommand.cs Resolved
Comment thread DevProxy/Commands/ValidateCommand.cs Resolved
- Resolve plugin config sections case-insensitively with ':' paths
- Report non-object root and non-string $schema as errors
- Emit JSON results via LogStructuredOutput
- Parse standalone validate args with System.CommandLine and allow
  global options before the command

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Read config properties case-insensitively, accept string booleans for
validateSchemas/enabled, error on non-string section $schema, and support
numeric array indices in configSection paths.

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The validator diverges from startup behavior, rejecting valid configurations and accepting duplicate keys that cause startup to fail.

No open issues 🎉

5 previously missed issues

In code that hasn't changed since last review

Medium severity Treat a null top-level schema as absent

DevProxy/​Commands/​ConfigCommand.cs:660

A top-level "$schema": null used to be treated as an absent schema, and startup likewise sees no schema URL. This new type check instead reports it as an error and exits 2, rejecting configurations that the proxy accepts. Treat JSON null as a missing schema and retain the existing no-schema warning.

Medium severity Skip section checks for non-configurable plugins

DevProxy/​Commands/​ConfigCommand.cs:867

This checks every referenced section even when the plugin does not support configuration. For example, RetryAfterPlugin inherits the non-generic BasePlugin, and RegisterPlugin ignores its configSection entirely; a stale section containing an invalid $schema will nevertheless make this command reject a configuration that starts normally. Use the loaded plugin type to skip section checks for non-configurable plugins, matching RegisterPlugin.

Medium severity Treat whitespace-only schema URLs as absent

DevProxy/​Commands/​ConfigCommand.cs:895

A whitespace-only schema URL is treated as absent by BasePlugin.ValidatePluginConfigAsync, but this check sends it to ValidateJsonAsync, which returns an error for the invalid URL. As a result, a configuration that the proxy accepts is reported invalid. Use the same whitespace check as startup.

Medium severity Resolve flattened colon-separated configuration keys

DevProxy/​Commands/​ConfigCommand.cs:931

Splitting the path only works when each segment is a separate JSON property. Configuration providers also flatten literal colon-containing keys, so a section such as "profiles:settings": {"$schema": "..."} is accessible at profiles:settings at startup but is reported missing here, and its schema is never checked. Resolve flattened keys as well as nested properties when traversing the path.

Medium severity Detect duplicate configuration keys case-insensitively

DevProxy/​Commands/​ConfigCommand.cs:967

The JSON configuration provider rejects duplicate flattened keys case-insensitively; it does not use the last value. For example, an otherwise-valid file containing both "urlsToWatch": ["https://a.example/*"] and "UrlsToWatch": ["https://b.example/*"] can pass this validator but fails at startup because both define the same array index. Detect duplicate configuration keys throughout the document and report a validation error instead of silently selecting the last value.

5 resolved since last review

Review effort: Balanced

Treat null and whitespace-only schema URLs as absent and report duplicate
configuration keys that would fail configuration loading.

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

Copy link
Copy Markdown
Collaborator Author

Addressed the "previously missed" items from the last review in 8b22509:

  • Null top-level $schema: now treated as absent and falls through to the existing no-schema warning.
  • Whitespace-only schema URLs: treated as absent, using the same check as startup (IsNullOrWhiteSpace).
  • Duplicate keys: the config is now loaded through the real JSON configuration provider, so duplicate keys (case-insensitive) are reported as configFile errors, just as startup would fail on them.

Pushing back on two items:

  • Skip section checks for non-configurable plugins: this would mean loading plugin assemblies from pluginPath during validation. That's heavier and has side effects (type loading, dependency resolution) that a quick, agent-friendly validate should avoid. Flagging an invalid $schema in a section that's referenced but unused is still useful feedback.
  • Flattened colon-containing keys: startup's own section schema check (BasePlugin.ValidatePluginConfigAsync) resolves the section with root.TryGetProperty(Key), not flattened keys, so this edge case isn't schema-validated at runtime either. The validator already resolves nested paths and array indices. I'd rather not add more traversal heuristics for a rare pattern.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

YAML configuration is checked with the JSON provider, causing valid YAML with case-insensitive key collisions to be rejected.

1 open issue

Review effort: Balanced

Comment thread DevProxy/Commands/ConfigCommand.cs Resolved
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Human assessment is needed because validation can diverge from runtime configuration and mistake schema retrieval failures for invalid settings.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

This branch has not been deployed

No deployments
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.

Consider adding a 'validate' command

2 participants