Skip to content

Fix Veeam x-api-version header sent as [object Object] - #124

Open
vinbab wants to merge 1 commit into
mainfrom
work/vb/plug-4730
Open

Fix Veeam x-api-version header sent as [object Object]#124
vinbab wants to merge 1 commit into
mainfrom
work/vb/plug-4730

Conversation

@vinbab

@vinbab vinbab commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

Fixes the x-api-version header 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 autocomplete control, which stores the whole { value, label } option object rather than the value string. Interpolating that straight into the header produced:

x-api-version: [object Object]

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:

[400] {"errorCode":"NotImplemented","message":"Unsupported RESTAPI version.
The following versions are supported: v1.0-rev1, v1.0-rev2, v1.1-rev0,
v1.1-rev1, v1.1-rev2, v1.2-rev0","resourceId":null}

The fix resolves the value in the header expression, handling both shapes: the object a dropdown selection produces, and the plain string defaultValue holds when the field is left untouched.

{{ typeof apiVersion === 'object' ? apiVersion.value : apiVersion }}

That dual handling also explains the reported symptom — data sources left on the default 1.3-rev1 sent 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: false is added so a free-text revision can't be typed in.

Note

This is a plugin-side workaround for a platform gap: autocomplete fields cannot currently yield a plain value string to plugin config (selectOptionsAs: 'valueString' isn't exposed to ui.json). Other shipped plugins that feed an autocomplete value into config are affected by the same issue — worth tracking separately.

Also worth a separate look: the base WebAPI plugin discards the token endpoint's response body on failure, surfacing only failed 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

  • Plugin name: Veeam Backup & Replication
  • Type of change:
    • Bug fix
    • New datastream
    • Enhancement to existing datastream
    • Performance improvement
    • Documentation / metadata / logo
    • Other (please describe):

🧪 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):

    [POST] request to [/api/oauth2/token] ... x-api-version: [object Object]
    

    After (this fix):

    [POST] request to [/api/oauth2/token] ... x-api-version: 1.3-rev1
    
  • 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 validate passes.

⚠️ Breaking changes

Does this PR introduce any breaking changes?

  • No
  • Yes (please describe):

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

  • Documentation updated
  • No documentation changes needed

The README already instructs users to pick the revision matching their server; no user-facing behaviour or option changed.

✅ Checklist

  • This PR changes a single plugin only
  • No secrets or credentials included
  • Plugin, datastream and UI naming follow SquaredUp guidelines
  • I agree to the Code of Conduct

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved API version handling for Veeam Backup & Replication authentication and requests.
    • API version settings now work consistently with both direct and structured values.
  • Improvements
    • Restricted API version selection to predefined options, preventing unsupported custom entries.
    • Updated the plugin metadata to version 1.0.1.

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>
@vinbab
vinbab requested a review from a team August 21, 2026 10:25
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 705f923e-9d88-4d44-9343-af9c53f34f1c

📥 Commits

Reviewing files that changed from the base of the PR and between 4c77c79 and 1d6f5f3.

📒 Files selected for processing (2)
  • plugins/VeeamBackupReplication/v1/metadata.json
  • plugins/VeeamBackupReplication/v1/ui.json

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.


📝 Walkthrough

Walkthrough

Changes

Veeam API version handling

Layer / File(s) Summary
API version configuration
plugins/VeeamBackupReplication/v1/metadata.json, plugins/VeeamBackupReplication/v1/ui.json
The plugin metadata version changes to 1.0.1. Both x-api-version headers support object-form and direct apiVersion values. The autocomplete field rejects custom values.

Merge Risk: ⚪ Minimal · up to 1d6f5

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)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main fix to the Veeam x-api-version header.
Description check ✅ Passed The description is complete and covers the fix, affected versions, testing, related issue, breaking changes, documentation, and checklist.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (2 skipped: 2 unsupported.)
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🧩 Plugin PR Summary

📦 Modified Plugins

  • plugins/VeeamBackupReplication/v1

📋 Results

Step Status
Scope & version ✅ Passed
Validation ✅ Passed
Deployment 🚀 Deployed

🔍 Validation Details

veeam-backup-replication
{
  "valid": true,
  "pluginName": "veeam-backup-replication",
  "pluginType": "hybrid",
  "summary": {
    "Data Streams": 4,
    "Import Definitions": 1,
    "Correlation Rules": 0,
    "UI Configuration": true,
    "Has Icon": true,
    "Has Default Content": true,
    "Config Validation": true,
    "Custom Types": true
  }
}

{ "key": "x-api-version", "value": "{{apiVersion}}" }
{
"key": "x-api-version",
"value": "{{ typeof apiVersion === 'object' ? apiVersion.value : apiVersion }}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have selectValueAs: string but not sure if should be default, or is accessible here?

@clarkd clarkd added the bug Something isn't working label Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Development

Successfully merging this pull request may close these issues.

3 participants