fix(api): accept version field in ClawHubInstallRequest (#6038)#6039
Conversation
51863db to
36235bc
Compare
…6038) The dashboard's clawhubInstall posts {slug, version, hand}, but ClawHubInstallRequest used #[serde(deny_unknown_fields)] without a version field, so the axum Json extractor rejected every ClawHub / clawhub-cn / skillhub install with 422 ("unknown field `version`"). Add version: Option<String> (#[serde(default)]); the installer still resolves to the latest published version, so the field is accepted to keep the request well-formed rather than driving version selection yet. The one shared type backs all three install endpoints, so this repairs POST /api/clawhub/install, /api/clawhub-cn/install and /api/skillhub/install. Regenerated openapi.json. Tests: clawhub_install_request_accepts_dashboard_body_with_version, clawhub_install_request_slug_only_still_works.
36235bc to
5dd2745
Compare
|
Re-reviewed after the latest push — this is a correct, well-scoped fix for the 422 and the two regression tests ( One thing worth a tracked follow-up (not blocking this PR): the field is accepted but silently ignored — the installer always resolves to latest, so a client that requests a specific |
houko
left a comment
There was a problem hiding this comment.
One finding during daily review pass:
Doc-comment mid-sentence line wrap in crates/librefang-api/src/types.rs
The doc comment for the version field wraps mid-sentence at ~80 chars:
/// Requested version (e.g., "latest"). The dashboard always sends this;
/// the installer currently resolves to the latest published version, so
/// the field is accepted to keep the request well-formed under
/// `deny_unknown_fields` rather than driving version selection yet.
CLAUDE.md (Prose wrapping section): "The only legitimate line break inside a paragraph is at a complete sentence boundary. This rule applies universally: … Source code doc-comments."
Fix — one sentence per line:
/// Requested version (e.g., "latest"). The dashboard always sends this; the installer currently resolves to the latest published version, so the field is accepted to keep the request well-formed under `deny_unknown_fields` rather than driving version selection yet.
After updating the Rust source, regenerate openapi.json (pre-commit hook / cargo xtask codegen openapi) to update the description string and xtask/baselines/openapi.sha256.
No other issues found; the serde fix and both regression tests look correct.
Generated by Claude Code
# Conflicts: # xtask/baselines/openapi.sha256
Summary
Closes #6038.
Installing any skill from the dashboard's ClawHub / SkillHub browser fails with
422 Unprocessable Entity.The dashboard's
clawhubInstall(dashboard/src/api.ts) posts{ slug, version, hand }, butClawHubInstallRequestwas declared#[serde(deny_unknown_fields)]with onlyslugandhand— noversion— so the axumJsonextractor rejected every request before the handler ran ("unknown fieldversion").The one shared
ClawHubInstallRequesttype backs three install handlers, so the single missing field broke all of them:POST /api/clawhub/install(routes/skills/clawhub.rs::clawhub_install)POST /api/clawhub-cn/install(routes/skills/clawhub.rs::clawhub_cn_install— China mirror)POST /api/skillhub/install(routes/skills/skillhub.rs::skillhub_install)Change
version: Option<String>with#[serde(default)]toClawHubInstallRequest(crates/librefang-api/src/types.rs).The installer still resolves to the latest published version — the field is accepted to keep the request well-formed under
deny_unknown_fields, not (yet) to drive version selection.slug-only bodies keep working.openapi.json(the type is autoipa::ToSchema); the pre-commit hook auto-syncedxtask/baselines/openapi.sha256.Verification
cargo check -p librefang-api— clean.cargo clippy -p librefang-api --all-targets -- -D warnings— clean.cargo test -p librefang-api --lib clawhub_install_request— 2/2 pass:clawhub_install_request_accepts_dashboard_body_with_version— the exact dashboard body{"slug","version","hand"}now deserializes.clawhub_install_request_slug_only_still_works— backward-compatible slug-only body.cargo xtask codegen --openapi— regenerated spec;ClawHubInstallRequest.propertiesnow listsslug,version,hand.Out-of-scope follow-ups
None. The handler ignoring
version(always installing latest) is intentional and documented on the field; wiring real version selection is a separate feature, not a regression.