From 5dcaac677bd268c9b434e4f4075f87206e7570fe Mon Sep 17 00:00:00 2001 From: evolv3ai Date: Mon, 15 Jun 2026 10:48:21 -0500 Subject: [PATCH] fix(backends/vastai): route /instances/ to /api/v1/ (v0 deprecated) Vast.ai deprecated /api/v0/instances/, returning HTTP 410 "deprecated_endpoint". dstack interprets that as "Invalid credentials" during auth_test() and refuses to register the backend. Only the /instances/ path family is deprecated; /bundles/ and /asks/ remain on v0 (v1 not yet published for them). The v1 instances response preserves the existing schema (success flag, instances list); it adds pagination fields the existing code ignores. Co-Authored-By: Claude Opus 4.7 --- src/dstack/_internal/core/backends/vastai/api_client.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dstack/_internal/core/backends/vastai/api_client.py b/src/dstack/_internal/core/backends/vastai/api_client.py index 1d8e4d8f3..7916f4e47 100644 --- a/src/dstack/_internal/core/backends/vastai/api_client.py +++ b/src/dstack/_internal/core/backends/vastai/api_client.py @@ -135,7 +135,13 @@ def auth_test(self) -> bool: return False def _url(self, path): - return f"{self.api_url}/{path.lstrip('/')}?api_key={self.api_key}" + base = self.api_url + # Vast.ai deprecated /api/v0/instances/ (HTTP 410). /api/v1/instances/ + # returns a schema-compatible response (success flag + instances list). + # /bundles/ and /asks/ remain on v0; v1 is not yet published for them. + if path.lstrip("/").startswith("instances/"): + base = base.replace("/api/v0", "/api/v1") + return f"{base}/{path.lstrip('/')}?api_key={self.api_key}" def _invalidate_cache(self): with self.lock: