fix: update commands honor the positional resource ID#89
Merged
Conversation
The platform's collection-style PUT endpoints (agents, prompts, custom-messages, language-groups, users, tools) route by an identifier inside the request body, not the URL. The update commands accepted a positional ID but never read it — the body's value silently decided which resource got updated, and --dry-run previews showed neither. A shared guard (ensureBodyIdentifier) now reconciles the two on all six commands: the positional is injected into the body when absent (id for agents/prompts/custom-messages/language-groups, email for users, name for tools), and a conflicting body value refuses the update instead of guessing. Dry-run previews now show the effective identifier. Closes #68 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
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.
The bug was worse than the issue title
#68 reported
--dry-runprinting a PUT URL without the resource ID. Root cause: the API's update endpoints are collection-style (PUT /api/v1/agents/) and route by the identifier inside the body — and the six body-routed update commands accepted a positional ID without ever reading it.syllable agents update 574 --file body.jsonupdated whateveridthe body contained; 574 was decoration. It worked daily only because the canonicalget → jq → updatepipe carries the rightidin the body.The fix
A shared guard,
ensureBodyIdentifier(cmd/root.go), applied to all six body-routed update commands:agents updateid(numeric)prompts updateid(numeric)custom-messages updateid(numeric)language-groups updateid(numeric)users updateemailtools updatename(body still routes by its numericid; the name is validated/injected)--dry-runpreviews now show the effective identifier in the body (the URL stays collection-style — that is genuinely what the API expects):{ "body": { "description": "noop", "id": 574 }, "dry_run": true, "method": "PUT", "url": ".../api/v1/agents/" }Commands whose updates already embed the ID in the URL (outbound, insights, directory, channels) were audited and are unaffected; body-only update commands (roles, services, data-sources, voice-groups, incidents) keep their existing contract.
Tests
TestEnsureBodyIdentifier— inject/match/conflict/non-numeric/string-key/non-object casesTestAgentsUpdateInjectsPositionalID— stub server receivesid: 574merged into the bodyTestAgentsUpdateConflictingBodyID— conflict errors before any request is sentTestUsersUpdateInjectsPositionalEmail,TestToolsUpdateValidatesPositionalNamego test ./...green locally.Closes #68
🤖 Generated with Claude Code