#180

Compiler accepts parameter schemas that exclude every RunInput parameter map

Opensdivyanshu90opened 9d ago

I found that compileBundle accepts query/path parameter schemas that can never accept the engine's parameter maps. For example, input.schema.queryParams: z.string() compiles, but an object fails its JSON Schema validation and a string fails the outer RunInput validation. This lets an unusable endpoint reach the catalog instead of giving its author a build error.

To reproduce with Deno 2, save the following as repro-params.ts in the repository root and run deno run --allow-read --allow-env repro-params.ts:

import {z} from "zod";
import {defineProvider, defineEndpoint, presets} from "@shared/core";
import {compileBundle} from "@shared/compiler";
import {validateInput} from "./engine/request.ts";
const provider = defineProvider({name:"demo",meta:{displayName:"Demo",summary:"Demo."},request:{baseUrl:"https://demo.test"},auth:{inject:presets.auth.header("x-key")},usage:{model:{kind:"FREE"}}});
for (const section of ["queryParams","pathParams"] as const) {
 const def=defineEndpoint({meta:{displayName:"Search",summary:"Search.",categories:["demo"]},request:{method:"GET",path:"/search"},input:{schema:{[section]:z.string()}}});
 const bundle=await compileBundle([{provider,endpoints:[{name:"search",def}]}],{compilerVersion:"0.1.0",builtWithEngineVersion:"0.5.0",catalogVersion:"0.0.0-test",generatedAt:"1970-01-01T00:00:00.000Z",leafCategories:[{id:"demo",displayName:"Demo"}]});
 console.log(section,"compiled");
 for (const value of [{}, {[section]:"value"}, {[section]:[]}]) {
  try { validateInput(bundle.endpoints["demo#search"],value); } catch(error) { console.log(String(error)); }
 }
}

For each section I get compiled, followed by three INVALID_INPUT errors:

  • An omitted value becomes {} and fails must be string.
  • A string fails expected record, received string.
  • An array fails expected record, received array.

I expect compilation to reject these parameter schemas with DOC_MALFORMED naming the endpoint and input section. Array and other scalar root types have the same problem, including schemas inherited from the provider.

schemaLeaf converts the resolved schema to JSON Schema without checking whether its type can accept a parameter map. The engine's zRunInput requires queryParams/pathParams to be records, and validateInput supplies an empty object when omitted.

I propose checking the resolved parameter schemas for explicit type restrictions that exclude objects, including such restrictions inside unions/intersections. The check should preserve object-capable compositions, unconstrained schemas, endpoint overrides, and non-object body schemas. This can be a conservative type compatibility check; it need not attempt general JSON Schema satisfiability or resolve references.

I searched open and closed issues and PRs for queryParams/pathParams schemas, non-object schemas, and root validation; I found no matching report or fix.

Activity

0

No activity yet.