[rig-sampler] fix(validation): improve minLength error message to include actual string length - #94
Conversation
…ring length When a string fails minLength validation, the previous error always said 'got empty string' even when the string was non-empty but too short. Now the message distinguishes the two cases: - empty string: 'expected string with minLength N, got empty string' - short string: 'expected string with minLength N, got string of length M' Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd — one observation on the new test coverage; no blocking issues.
📋 Key Themes & Highlights
Key Themes
- Test type-safety: The new test for non-empty too-short strings uses a type cast (
as ReturnType<typeof s.string>) to inject a raw schema object that the public API can't produce. The comment inside the test acknowledges this. The test works, but it validates an unreachable code path from the caller's perspective — worth either exposingminLengthas a propers.stringoption or testingvalidateSchemadirectly.
Positive Highlights
- ✅ Fix in
rig.tsis minimal, correct, and well-scoped: one conditional, no side effects - ✅ Existing empty-string test updated to assert on the specific message token (
"empty string"), tightening coverage - ✅ PR description clearly explains the motivation (repair-loop confusion) and the before/after behaviour
- ✅ The two-branch ternary (
value.length === 0 ? ... : ...) reads cleanly and matches the intent exactly
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 32.7 AIC · ⌖ 7.04 AIC · ⊞ 6.3K
Comment /matt to run again
| // Use s.nonEmptyString (minLength:1) against "" for the empty branch, | ||
| // and build a custom schema object for minLength > 1: | ||
| const minLen5Schema = { type: "string" as const, minLength: 5 }; | ||
| const wrappedSchema = s.object({ code: minLen5Schema as ReturnType<typeof s.string> }); |
There was a problem hiding this comment.
[/tdd] The test uses minLen5Schema as ReturnType<typeof s.string> to force a raw schema object past TypeScript — a type-unsound workaround that the inline comment itself flags as a limitation.
If s.string does not support a minLength argument through the public API, that gap is worth addressing. Using a type cast here means the test validates behaviour that callers cannot legally trigger through the public API.
💡 Cleaner alternatives
Option A — expose a minLength option on s.string (or a s.string({ minLength: N }) overload) so the test is type-safe:
const schema = s.object({ code: s.string({ minLength: 5 }) });Option B — if this path is intentionally internal, test validateSchema directly (if exported) without going through analyzeResponse with a cast:
const result = validateSchema("ab", { type: "string", minLength: 5 }, "code", false);
expect(result).toEqual({ ok: false, error: "code: expected string with minLength 5, got string of length 2" });Either option removes the cast, keeps the test type-safe, and makes the test read as a specification of real, reachable behaviour.
Samples Run
The following five samples were executed via
RIG_SAMPLE=N npm run sample(stub Copilot SDK):01-single-agent-haiku.ts02-review-git-diff.tsfindingsarray, 2 ask events (initial + sub-agent), no repair03-diagnose-test-failure.tsrisk,severity), 2 ask events, no repair04-generate-readme.tsrootCause,confidence(number), arrays; 2 ask events05-write-readme-intent.tspathconstrained tos.literal("README.md"),contentsstring; usesp.read+p.bashintentsAnalysis
s.enumforrisk/severityfields — appropriate and tight. Sample 05 usess.literal("README.md")forpath— good use of a single-value constraint.validateSchema. When a string value fails theminLengthcheck, the error always reported "got empty string" — even when the actual value was non-empty but shorter than the minimum length. In a repair loop, this confuses the model: it may be told the string was empty when it actually provided a short non-empty value.Change
In
skills/rig/rig.ts, theminLengthvalidation branch now distinguishes:"got empty string"(unchanged behavior for the common case)"got string of length M"(new, more accurate message)This improves repair prompt quality when
s.nonEmptyStringor a customminLengthconstraint rejects a short value — the model now sees the actual length rather than a misleading "empty string" label.A new test case in
src/rig.test.tscovers the non-empty too-short path alongside the existing empty-string test.