Summary
BindParams takes the formal-parameter branch whenever a declaration exists and binds p.Default even when it is nil (rendering NULL), so resolution never falls through to the inline {{name:default}} or to the "missing required parameter" 400.
Detail
internal/pipes/pipes.go:192-202:
if v, ok := supplied[name]; ok { val = v }
else if p, ok := formal[name]; ok { val = p.Default } // nil Default -> NULL
else if inlineDefault != "" { val = inlineDefault }
else { bindErr = missing required parameter }
Docs (docs/src/content/docs/pipes.mdx, "How a value is resolved") promise: declared default only if one is given, then inline default, then 400.
Scenario: pipe SELECT * FROM clicks WHERE page = {{page}} with parameters: [{"name":"page","type":"string"}] (author forgot required: true) and a caller omitting page → silent WHERE page = NULL (always-empty 200 instead of 400). With LIMIT {{limit:100}} plus a defaultless limit declaration, the inline 100 is ignored and LIMIT NULL errors (a #271-class 500).
Note: TestBindParams_NilParam (pipes_test.go:161-170) pins the explicit-Default: nil case, which JSON can't distinguish from an absent default — a fix must pick a side and update docs or code/test.
Fix direction
Only use a declared default when one was actually provided (track presence separately from nil), then fall through to inline default / 400.
Found in a repo-wide audit; verified by code trace. Sibling of #363's "inline empty default treated as required".
Summary
BindParamstakes the formal-parameter branch whenever a declaration exists and bindsp.Defaulteven when it is nil (renderingNULL), so resolution never falls through to the inline{{name:default}}or to the "missing required parameter" 400.Detail
internal/pipes/pipes.go:192-202:Docs (
docs/src/content/docs/pipes.mdx, "How a value is resolved") promise: declared default only if one is given, then inline default, then 400.Scenario: pipe
SELECT * FROM clicks WHERE page = {{page}}withparameters: [{"name":"page","type":"string"}](author forgotrequired: true) and a caller omittingpage→ silentWHERE page = NULL(always-empty 200 instead of 400). WithLIMIT {{limit:100}}plus a defaultlesslimitdeclaration, the inline100is ignored andLIMIT NULLerrors (a #271-class 500).Note:
TestBindParams_NilParam(pipes_test.go:161-170) pins the explicit-Default: nilcase, which JSON can't distinguish from an absent default — a fix must pick a side and update docs or code/test.Fix direction
Only use a declared default when one was actually provided (track presence separately from nil), then fall through to inline default / 400.
Found in a repo-wide audit; verified by code trace. Sibling of #363's "inline empty default treated as required".