Repository navigation
Negotiate the API version with the server - #13
Merged
Merged
Conversation
The api-version-negotiation backlog entry starts: it is broken down into a tasks file and removed from the backlog. TASK-08 of the first-run errors file, the next step for a POST refused for lack of a version, moves into the new file as TASK-04, rewritten for a refusal that follows a failed negotiation. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015w3YJNX9AzYUZq25WyQFDp
The findings come from the Go SDK, which on-premises servers share with the others: OPTIONS on the collection's _apis returns every resource location with its versions, and a location is identified by its id. tfscli matches by id as the SDK does, since the pair of area and resource name is not documented as unique and the work items resource already has two locations. The refusal of a request without a version carries the typeKey VssVersionNotSpecifiedException in a report from Azure DevOps Services; the on-premises behaviour and the OPTIONS response of TFS 2015 and 2017 remain unverified, which the fallback covers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015w3YJNX9AzYUZq25WyQFDp
Without a configured version, every request is now preceded by OPTIONS on the collection's _apis and carries the released version the server lists for its resource location, or the latest preview when there is none. That is the version the server would choose for a request without one, so the output of the GET commands does not change, while the POST commands stop depending on the server accepting a request without a version. Each caller names its resource location by the id the SDKs use, so Get and Post take a location; the login check passes none and stays unversioned. A 401 or a transport failure on OPTIONS fails the command at once, since the request itself would fail the same way. Any other failure falls back to the request without a version, as before, and says why under --verbose through a new Info method of the logger: the line reports what tfscli did on its own, which a warning would misdescribe. The two tasks are committed together because the version selection alone would be unused code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015w3YJNX9AzYUZq25WyQFDp
When negotiation fails and the server then refuses the request for carrying no API version, the error now says why the version could not be negotiated, where a version is set, and that it must not exceed what the server supports. The refusal is recognised by its typeKey, VssVersionNotSpecifiedException, and by the start of its English message only when the server sends no typeKey, since the message follows the language the server is installed in. A request refused without a fallback keeps the server's message, as does a refusal of a configured version. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015w3YJNX9AzYUZq25WyQFDp
The project brief records the product decision: the API version is negotiated with the server rather than left out, because some servers refuse a POST request without one, and the fallback to a request without a version keeps every server tfscli worked with working. CLAUDE.md, the architecture, the README, the agent skill, and the --api-version help follow it, and the changelog records the change for users. Closes docs/archive/2026-10-06-tasks-api-version-negotiation.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015w3YJNX9AzYUZq25WyQFDp
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.
Without a configured API version,
wit work-items get-batchandwit wiql query-by-wiqlfailed on servers that refuse a POST request without one, and the user had no way to know which version to set. tfscli now does what the official SDKs do:auth loginfirst sendsOPTIONS {collection}/_apisand uses the version the server lists for its resource. Without a version the server would answer at that same version, so the output does not change.--verbosesays why in an[info]line. If the server then refuses the request for the missing version, theconfigerror namesapiVersion,TFSCLI_API_VERSION, and--api-version.OPTIONS.The project brief,
CLAUDE.md, the architecture, the README, the agent skill, and the changelog are updated. The research and the decisions are indocs/archive/2026-10-06-tasks-api-version-negotiation.md.