From c2d2f34afc3691d58c8bfafe81923a5468fefe85 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:32:25 +0000 Subject: [PATCH 1/2] Initial plan From 7440bbb35f0767dd7753e6c6c8a735b2708770ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:39:56 +0000 Subject: [PATCH 2/2] fix(openapi): document deferred spec_file validation and add enum scalar tests Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- module/openapi_test.go | 6 ++++++ plugins/openapi/plugin.go | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/module/openapi_test.go b/module/openapi_test.go index 18527664..e8f0cadb 100644 --- a/module/openapi_test.go +++ b/module/openapi_test.go @@ -516,6 +516,12 @@ func TestValidateScalarValue(t *testing.T) { {"string too long", "toolongstring", &openAPISchema{Type: "string", MaxLength: &maxLen}, true}, {"enum match", "cat", &openAPISchema{Type: "string", Enum: []any{"cat", "dog"}}, false}, {"enum mismatch", "fish", &openAPISchema{Type: "string", Enum: []any{"cat", "dog"}}, true}, + // Query/path parameters are always strings; integer enum values from YAML + // (e.g. enum: [1, 2, 3]) are compared as their string representation. + // This is intentional: the parameter "1" should match the YAML integer 1. + {"enum integer yaml matches string param", "1", &openAPISchema{Type: "integer", Enum: []any{1, 2, 3}}, false}, + {"enum integer yaml no match", "4", &openAPISchema{Type: "integer", Enum: []any{1, 2, 3}}, true}, + {"enum nil values skipped", "a", &openAPISchema{Enum: []any{nil, "a", nil}}, false}, } for _, tt := range tests { diff --git a/plugins/openapi/plugin.go b/plugins/openapi/plugin.go index d9cf4596..c9f5d90c 100644 --- a/plugins/openapi/plugin.go +++ b/plugins/openapi/plugin.go @@ -58,6 +58,11 @@ func (p *Plugin) ModuleFactories() map[string]plugin.ModuleFactory { "openapi": func(name string, cfg map[string]any) modular.Module { oacfg := module.OpenAPIConfig{} + // NOTE: spec_file existence is not validated here at configuration time. + // Path resolution is performed by ResolvePathInConfig (relative to the + // config file directory via the _config_dir key), but file existence and + // readability are checked lazily during Init(). Errors will surface at + // engine startup, after all modules have been constructed. if v, ok := cfg["spec_file"].(string); ok { oacfg.SpecFile = config.ResolvePathInConfig(cfg, v) }