Resolve relative --project-root before the API call - #6223
Merged
Conversation
A relative --project-root travelled verbatim to the API server, which requires an absolute path, so the command failed with a validation error naming the wire field (project_root) rather than the flag the user typed. For upgrade this also surfaced as exit 1, outside its documented 0/2/3/4 exit-code contract, so CI branching on those codes saw an unexpected value. Empty stays empty: for most skill commands that means "not project-scoped", and substituting the working directory would silently change the scope. Closes #6211
samuv
requested review from
ChrisJBurns,
JAORMX,
amirejaz,
aponcedeleonch,
jhrozek,
rdimitrov and
reyortiz3
as code owners
August 6, 2026 07:52
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6223 +/- ##
==========================================
+ Coverage 72.48% 72.50% +0.02%
==========================================
Files 739 739
Lines 76728 76728
==========================================
+ Hits 55613 55635 +22
+ Misses 17151 17110 -41
- Partials 3964 3983 +19 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
JAORMX
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--project-root .is the natural thing to write when scriptingthv skillcommands, but it does not work. The CLI forwards the flag verbatim to the API server, which requires an absolute path, so the command fails with a validation error naming the wire field rather than the flag the user typed:Two things made this worse than a cosmetic message problem:
--project-rootis omitted) is absolute, so the flag behaved differently from its own default — surprising, and only at the point of failure.thv skill upgradeexited 1, outside its documented 0/2/3/4 exit-code contract. A CI job branching on those codes sees an unexpected value instead of a clear failure.What changed:
absProjectRoothelper inskill_helpers.goresolves a user-supplied value withfilepath.Abs, and leaves an empty value empty — for most skill commands empty means "not project-scoped", so substituting the working directory would silently change the scope.resolveProjectRoot(sync, upgrade) now absolutizes the explicit branch, which previously short-circuited untouched.install,info,list, anduninstallnormalize before building their options.Closes #6211
Type of change
Test plan
task test)task lint-fix)New table-driven
TestAbsProjectRootcovers empty /./ relative child / already-absolute / traversal-cleaning, plusTestResolveProjectRootAbsolutizesExplicitpinning the specific branch that regressed.Manually, against a local
thv serve:and confirmed the server-side validation is unchanged — it still rejects a relative root, so the normalization is genuinely happening client-side:
Does this introduce a user-facing change?
Yes.
thv skillcommands now accept a relative--project-root(including.), resolving it against the working directory. Absolute paths behave exactly as before.Special notes for reviewers
Deliberately scoped to
thv skill, matching the issue. Thethv ai-plugincommands take the same flag and validate through the parallelpkg/plugins/validator.go, so they almost certainly have the identical bug — happy to fix them here instead if you'd rather it were one sweep, but it seemed better not to widen a bug fix into a package the issue never mentioned.Generated with Claude Code