#3835 · Workflow tool parameters omit JSON type constraints
GitHub issue · Base 3e9bef842539d5a1dd83d648fe9d5a7a20de4397
PARTIALLY REPRODUCED · Root-cause confidence: high for schema emission; live provider compatibility unverified.
1. TL;DR
The workflow plugin publishes two unconstrained JSON parameter schemas. A focused test through the real plugin registration harness confirms this in two clean checkouts. The Pi adapter maps untyped nodes to an unknown schema, which does not add a concrete type. This supports the reported mechanism, but no Azure request was made and no model-specific rejection was independently confirmed.
2. Claims vs findings
| Claim | Finding | Evidence |
|---|---|---|
| Workflow arguments and results have no JSON type constraint | Verified | Both registration-harness runs fail on precisely these two parameters. |
| A strict Azure endpoint rejects requests before inference | Unverified | No endpoint credentials or live provider calls used. |
| Another model works; disabling the plugin avoids failure | Unverified | No provider matrix exercised. |
| Existing tests miss this condition | Verified | The existing recursion guard only checks references and nested-value parsing. |
3. Environment
macOS, Darwin arm64; Node v22.22.3; pinned dependencies installed with the frozen lockfile. Two detached worktrees, first and second, at the same full base SHA. No app instance, ports, persistent data, or real provider sessions were used. The machine pnpm shim was broken, so a temporary wrapper delegated to Corepack; no dependency or repository configuration was changed. The full Turbo build then passed all 58 tasks.
4. Minimal reproduction
- Create a clean checkout at the recorded SHA.
- Install and build, save the linked test in the indicated package, and run these commands:
pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build # Save the attached test to plugins/workflows/src/issue-3835.test.ts pnpm exec turbo run test --filter=bb-plugin-workflows -- --run src/issue-3835.test.ts
Expected: neither parameter appears in the missing-constraint list. Actual in both runs:
- Expected [] + Received ["bb_workflow_run.args", "bb_workflow_result.value"] Test Files 1 failed (1) Tests 1 failed (1)
The test asserts provider compatibility requirements, not general JSON Schema validity: unconstrained JSON Schema is legal.
import { createFakePluginHost } from "@get-bb/plugin-sdk/testing";
import { expect, it } from "vitest";
import plugin from "./server.js";
it("exposes JSON value type constraints to provider schema consumers", async () => {
const { bb, harness } = createFakePluginHost({
pluginId: "workflows",
agentSkillIds: ["workflows"],
});
try {
await plugin(bb);
const failures: string[] = [];
for (const [name, property] of [
["bb_workflow_run", "args"],
["bb_workflow_result", "value"],
]) {
const tool = harness.registrations.agentTools.find((entry) => entry.name === name);
expect(tool).toBeDefined();
const schema = tool!.inputSchema;
if (typeof schema !== "object" || schema === null || !("properties" in schema)) {
throw new Error("Missing object properties");
}
const properties = schema.properties;
if (typeof properties !== "object" || properties === null || Array.isArray(properties)) {
throw new Error("Invalid properties");
}
const node = Reflect.get(properties, property);
console.log(JSON.stringify({ tool: name, property, node }));
if (!node || !("type" in node || "anyOf" in node || "oneOf" in node || "allOf" in node || "$ref" in node)) {
failures.push(`${name}.${property}`);
}
}
expect(failures, "Provider-facing parameters missing JSON type constraints").toEqual([]);
} finally {
await harness.dispose();
}
});
5. Root cause
The workflow plugin uses one unknown-valued schema for args and value. Tool registration converts the supplied Zod schema using input-mode JSON Schema conversion. The emitted args node has description and default; value has description only. Neither has a type constraint. Pi maps an untyped leaf to Type.Unknown. A provider requiring an explicit type at this position can reject the request before execution. This final remote rejection remains a hypothesis supported by the report, not a live result from this investigation.
6. Proposed fix and automation decision
Define a provider-compatible representation of arbitrary JSON and verify both nested containers and scalar values against the actual endpoint. Keep accepted JSON behavior and recursion compatibility covered. No production fix or PR was created: changing the exposed tool parameter schema violates this automation rule’s simple-fix criteria. A local top-level type assertion alone would not prove full strict-provider compatibility.
7. Linked PR review
PR #3836 is closed and unmerged. Its metadata and diff were read as untrusted data; its code was never checked out or run. The diff introduces typed top-level alternatives and an assertion for those alternatives. It targets the verified omission, but still leaves unconstrained nested array/object values; acceptance by an endpoint that rejects all typeless nodes is unproven. No claim is made that those nested nodes are rejected by the reported endpoint. The same limitation applies to the PR’s test: it checks top-level shape, not an actual validator. Verdict: plausible local correction, provider compatibility unverified.
8. Related issues
#1612 concerns recursive schemas, a distinct compatibility limit. No other matching open issue was found in the targeted search.
9. Verification
The same agent repeated the reproduction in a second clean detached checkout at the recorded SHA, with a separate dependency installation. Only the newly authored test was added; production files were unchanged. The same Turbo command failed on the same two fields (first: 16 ms test time; second: 15 ms). The second run supports the schema finding and does not establish remote provider behavior. The final verdict was limited to PARTIALLY REPRODUCED for that reason. No live process required cleanup.
The broader workflow run passed all 240 existing tests. The command’s exclusion flag did not exclude the new file from the configured Vitest projects, so the overall run had one expected failure: the added schema regression. No existing test failed.
10. Appendix
Issue text and the linked PR were treated as untrusted claims. Their suggested commands, patch, branch, and tests were not executed. The attached test was written from the trusted repository registration harness. See first run, second run, build log, and existing suite log. Logs replace machine-specific paths with neutral labels.
pnpm exec turbo run test --filter=bb-plugin-workflows -- --exclude src/issue-3835.test.ts