@@ -155,6 +155,23 @@ type FieldVersionMismatchError struct {
155155func (e * FieldVersionMismatchError ) Error () string { return e .Cause .Error () }
156156func (e * FieldVersionMismatchError ) Unwrap () error { return e .Cause }
157157
158+ // ForbiddenFieldError clusters "field X must not be set in this
159+ // context" failures (header.name and header.in inside a Headers map,
160+ // OAuth flow URLs that don't apply to the chosen flow type).
161+ type ForbiddenFieldError struct {
162+ // Field is the name of the forbidden field (e.g. "name", "in",
163+ // "authorizationUrl", "tokenUrl").
164+ Field string
165+ // Cause is the underlying leaf error. Walked by errors.Unwrap.
166+ Cause error
167+ // Origin is the source location of the offending element when the
168+ // document was loaded with Loader.IncludeOrigin = true.
169+ Origin * Origin
170+ }
171+
172+ func (e * ForbiddenFieldError ) Error () string { return e .Cause .Error () }
173+ func (e * ForbiddenFieldError ) Unwrap () error { return e .Cause }
174+
158175// ---------------------------------------------------------------------
159176// Leaf types — one per call site. Each embeds ValidationError for
160177// Error() and As-to-base, and is wrapped in its cluster type when
@@ -198,6 +215,32 @@ func (e *ServerURLRequired) As(target any) bool {
198215 return asValidationError (target , & e .ValidationError )
199216}
200217
218+ // ForbiddenFieldError leaves.
219+
220+ type HeaderNameForbidden struct { ValidationError }
221+
222+ func (e * HeaderNameForbidden ) As (target any ) bool {
223+ return asValidationError (target , & e .ValidationError )
224+ }
225+
226+ type HeaderInForbidden struct { ValidationError }
227+
228+ func (e * HeaderInForbidden ) As (target any ) bool {
229+ return asValidationError (target , & e .ValidationError )
230+ }
231+
232+ type OAuthFlowAuthorizationURLForbidden struct { ValidationError }
233+
234+ func (e * OAuthFlowAuthorizationURLForbidden ) As (target any ) bool {
235+ return asValidationError (target , & e .ValidationError )
236+ }
237+
238+ type OAuthFlowTokenURLForbidden struct { ValidationError }
239+
240+ func (e * OAuthFlowTokenURLForbidden ) As (target any ) bool {
241+ return asValidationError (target , & e .ValidationError )
242+ }
243+
201244// FieldVersionMismatchError leaves — non-schema fields.
202245
203246type InfoSummaryFieldFor31Plus struct { ValidationError }
@@ -414,6 +457,36 @@ func newServerURLRequired(origin *Origin) error {
414457 & ServerURLRequired {ValidationError {Message : "value of url must be a non-empty string" }}, origin )
415458}
416459
460+ // newForbiddenField wraps leaf in a *ForbiddenFieldError carrying the
461+ // name of the field that the spec forbids in the current context.
462+ func newForbiddenField (field string , leaf error , origin * Origin ) error {
463+ return & ForbiddenFieldError {Field : field , Cause : leaf , Origin : origin }
464+ }
465+
466+ func newHeaderNameForbidden (origin * Origin ) error {
467+ const msg = "header 'name' MUST NOT be specified, it is given in the corresponding headers map"
468+ return newForbiddenField ("name" ,
469+ & HeaderNameForbidden {ValidationError {Message : msg }}, origin )
470+ }
471+
472+ func newHeaderInForbidden (origin * Origin ) error {
473+ const msg = "header 'in' MUST NOT be specified, it is implicitly in header"
474+ return newForbiddenField ("in" ,
475+ & HeaderInForbidden {ValidationError {Message : msg }}, origin )
476+ }
477+
478+ func newOAuthFlowAuthorizationURLForbidden (origin * Origin ) error {
479+ const msg = "field 'authorizationUrl' should not be set"
480+ return newForbiddenField ("authorizationUrl" ,
481+ & OAuthFlowAuthorizationURLForbidden {ValidationError {Message : msg }}, origin )
482+ }
483+
484+ func newOAuthFlowTokenURLForbidden (origin * Origin ) error {
485+ const msg = "field 'tokenUrl' should not be set"
486+ return newForbiddenField ("tokenUrl" ,
487+ & OAuthFlowTokenURLForbidden {ValidationError {Message : msg }}, origin )
488+ }
489+
417490// newSchemaValueError wraps the result of schema.VisitJSON in a
418491// *SchemaValueError cluster, identifying which schema sub-field
419492// (example, default, ...) carried the offending value. cause is
0 commit comments