E07731: each HTTP PATH variable must be bound by exactly one PATH parameter
What went wrong
Each path variable in a service operation's URI must appear only once and be bound by exactly ONE PATH parameter. Matching counts are not enough: two parameters bound to the same variable make up the number for a variable that nothing binds, so a request segment would silently never reach the operation.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 946 (How must path variable counts match parameters in EK9 services?)
How to fix it
- Bind every path variable with exactly one PATH parameter
- Give each path variable a distinct name within the URI
The [EXAMPLE] section below shows one variable bound twice (explicitly, and once by an inferred name) and one repeated in the URI, then each variable bound exactly once.
Common causes
- Copying a parameter line and not changing its PATH "name"
- An inferred PATH parameter (named like the variable) plus an explicit :=: PATH to the same variable
- Reusing one variable name twice in the URI
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E07731: each HTTP PATH variable must be bound by exactly one PATH parameter
#!ek9 defines module error.e07731.bad defines service Items for :/items open //Valid control: each placeholder bound once. pair() for :/{a}/{b}/pair.html -> first as String :=: PATH "a" second as String :=: PATH "b" <- response as HTTPResponse: () with trait of HTTPResponse //Both explicit parameters bind {a}; {b} is never bound. twiceExplicit() for :/{a}/{b}/twiceExplicit.html -> first as String :=: PATH "a" second as String :=: PATH "a" <- response as HTTPResponse: () with trait of HTTPResponse //'a' is an inferred PATH "a" binding, and the explicit parameter binds {a} again; {b} unbound. twiceInferred() for :/{a}/{b}/twiceInferred.html -> a as String other as String :=: PATH "a" <- response as HTTPResponse: () with trait of HTTPResponse //The same placeholder twice in one URI has no single meaning, so it is rejected outright. repeated() for :/{a}/{a}/repeated.html -> first as String :=: PATH "a" second as String :=: PATH "a" <- response as HTTPResponse: () with trait of HTTPResponse
Fixed: Bind each path variable once
#!ek9 defines module error.e07731.good defines class TextResponse with trait of HTTPResponse text as String? default private TextResponse() TextResponse() -> body as String this.text: body override contentType() as pure <- rtn as String: "text/plain" override content() <- rtn as Bytes: Bytes().withUtf8(text) override status() as pure <- rtn as Integer: 200 default operator ? defines service Items for :/items open //Each variable bound exactly once pair() as GET for :/{a}/{b}/pair.html -> first as String :=: PATH "a" second as String :=: PATH "b" <- response as HTTPResponse: TextResponse(`${first} ${second}`)