Fix Veeam x-api-version header sent as [object Object] - #124
Conversation
The REST API version field uses the `autocomplete` control, which stores the
whole `{value, label}` option object rather than the value string. Interpolating
it straight into the header produced `x-api-version: [object Object]`.
Veeam 13 tolerates the invalid value and falls back to its latest revision, so
this went unnoticed. Veeam 12 correctly rejects it, failing the token request:
[400] {"errorCode":"NotImplemented","message":"Unsupported RESTAPI version.
The following versions are supported: v1.0-rev1, ... v1.2-rev0"}
Resolve the value in the header expression instead, handling both shapes - the
object a dropdown selection produces and the plain string that `defaultValue`
holds when the field is untouched (which is why only v12 setups, where the
revision must be changed from the default, ever failed).
Keeps the dropdown and its options, labels, default and help text unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Included review availability: 4 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. 📝 WalkthroughWalkthroughChangesVeeam API version handling
Merge Risk: ⚪ Minimal · up to This localized fix ensures the REST API version is sent as a valid string for both default and selected values, restoring compatibility for affected Veeam connections. No actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
🧩 Plugin PR Summary📦 Modified Plugins
📋 Results
🔍 Validation Details✅
|
| { "key": "x-api-version", "value": "{{apiVersion}}" } | ||
| { | ||
| "key": "x-api-version", | ||
| "value": "{{ typeof apiVersion === 'object' ? apiVersion.value : apiVersion }}" |
There was a problem hiding this comment.
I think this probably points to a bug with the autocomplete somewhere - you shouldn't need to access .value here IMO. Any thoughts @kieranlangton @andrewmumblebee ?
There was a problem hiding this comment.
We have selectValueAs: string but not sure if should be default, or is accessible here?
📋 Summary
Fixes the
x-api-versionheader being sent as the literal string[object Object], which broke the plugin against Veeam Backup & Replication 12.x.The REST API version field uses the
autocompletecontrol, which stores the whole{ value, label }option object rather than the value string. Interpolating that straight into the header produced:Veeam 13 tolerates the invalid value and falls back to its latest revision, so the plugin appeared to work and this went unnoticed. Veeam 12 correctly rejects it, failing the token request before credentials are even considered:
The fix resolves the value in the header expression, handling both shapes: the object a dropdown selection produces, and the plain string
defaultValueholds when the field is left untouched.That dual handling also explains the reported symptom — data sources left on the default
1.3-rev1sent a valid string and worked, while only v12 setups failed, because those are precisely the ones where the revision must be changed from the default.The dropdown, its options, labels, default and help text are unchanged.
allowCustomValues: falseis added so a free-text revision can't be typed in.Note
This is a plugin-side workaround for a platform gap:
autocompletefields cannot currently yield a plain value string to plugin config (selectOptionsAs: 'valueString'isn't exposed toui.json). Other shipped plugins that feed anautocompletevalue into config are affected by the same issue — worth tracking separately.Also worth a separate look: the base
WebAPIplugin discards the token endpoint's response body on failure, surfacing onlyfailed with status 400. Veeam had been returning the precise reason above the whole time; capturing that body would have made this a minutes-long diagnosis.🔗 Related issue(s)
PLUG-4730. Raised from a customer support case where v13 worked but v12.3.2 failed with a generic 400.
🧩 Plugin details
🧪 Testing
Deployed to a SquaredUp dev organization and exercised against two live VBR servers reachable through a SquaredUp Agent.
Verified in Veeam's own REST API service log (
Svc.VeeamRestAPI.log) that the header is now correct — this is the definitive before/after:Before (broken):
After (this fix):
Confirmed with a non-default revision selected from the dropdown (the action that previously corrupted the header), and with the field left at its default — both now send a valid revision string.
Existing data sources, config validation, object import and all four data streams continue to work;
squaredup validatepasses.Does this PR introduce any breaking changes?
Existing data sources are unaffected in behaviour — those on the default revision were already sending a valid header. Anyone whose v12 connection was failing should re-save their data source after this ships.
📚 Documentation
The README already instructs users to pick the revision matching their server; no user-facing behaviour or option changed.
✅ Checklist
🤖 Generated with Claude Code
Summary by CodeRabbit