Skip to content

Instantly share code, notes, and snippets.

@glennpratt
Last active February 18, 2026 00:57
Show Gist options
  • Select an option

  • Save glennpratt/e427a03cb749ccec3c3041c6e6396aea to your computer and use it in GitHub Desktop.

Select an option

Save glennpratt/e427a03cb749ccec3c3041c6e6396aea to your computer and use it in GitHub Desktop.
Linodego bug check
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"github.com/linode/linodego"
"golang.org/x/oauth2"
)
func main() {
token := os.Getenv("LINODE_TOKEN")
if token == "" {
log.Fatal("LINODE_TOKEN environment variable must be set")
}
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
oauth2Client := &http.Client{
Transport: &oauth2.Transport{
Source: tokenSource,
},
}
client := linodego.NewClient(oauth2Client)
ctx := context.Background()
regionID := "us-sea"
fmt.Println("Testing GetRegionAvailability bug...")
fmt.Printf("Calling GetRegionAvailability for region: %s\n\n", regionID)
// This should fail or return incorrect data because the API returns an array
// but the function expects a single object
availability, err := client.GetRegionAvailability(ctx, regionID)
if err != nil {
fmt.Printf("❌ Error (as expected): %v\n\n", err)
// Let's also make a raw HTTP call to show what the API actually returns
fmt.Println("Making raw API call to show actual response format:")
showRawAPIResponse(token, regionID)
} else {
fmt.Printf("⚠️ Unexpected success - got result: %+v\n", availability)
fmt.Println("This shouldn't work since API returns an array, not a single object")
}
// For comparison, list all region availability (which correctly handles arrays)
fmt.Println("\n---")
fmt.Println("For comparison, ListRegionsAvailability works correctly:")
allAvailability, err := client.ListRegionsAvailability(ctx, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
// Filter to just the region we care about
count := 0
for _, av := range allAvailability {
if av.Region == regionID {
count++
}
}
fmt.Printf("✅ Successfully got %d availability records for region %s\n", count, regionID)
if count > 0 {
fmt.Println("First few records:")
shown := 0
for _, av := range allAvailability {
if av.Region == regionID && shown < 3 {
fmt.Printf(" - Plan: %s, Available: %t\n", av.Plan, av.Available)
shown++
}
}
}
}
}
func showRawAPIResponse(token, regionID string) {
url := fmt.Sprintf("https://api.linode.com/v4/regions/%s/availability", regionID)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("Failed to create request: %v\n", err)
return
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Failed to make request: %v\n", err)
return
}
defer resp.Body.Close()
var result []map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
fmt.Printf("Failed to decode response: %v\n", err)
return
}
fmt.Printf("✅ Raw API returns an ARRAY with %d elements\n", len(result))
if len(result) > 0 {
fmt.Println("First 3 elements:")
for i := 0; i < 3 && i < len(result); i++ {
jsonBytes, _ := json.MarshalIndent(result[i], " ", " ")
fmt.Printf(" %s\n", string(jsonBytes))
}
}
}
❯ go run ./bugcheck/test_region_availability_bug.go
Testing GetRegionAvailability bug...
Calling GetRegionAvailability for region: us-sea
2026/02/17 19:35:14.910336 WARN RESTY json: cannot unmarshal array into Go value of type linodego.RegionAvailability, Attempt 1
2026/02/17 19:35:14.910440 ERROR RESTY json: cannot unmarshal array into Go value of type linodego.RegionAvailability
❌ Error (as expected): [002] json: cannot unmarshal array into Go value of type linodego.RegionAvailability
Making raw API call to show actual response format:
✅ Raw API returns an ARRAY with 72 elements
First 3 elements:
{
"available": true,
"plan": "g6-standard-1",
"region": "us-sea"
}
{
"available": true,
"plan": "g6-standard-2",
"region": "us-sea"
}
{
"available": true,
"plan": "g6-standard-4",
"region": "us-sea"
}
---
For comparison, ListRegionsAvailability works correctly:
✅ Successfully got 72 availability records for region us-sea
First few records:
- Plan: g6-standard-1, Available: true
- Plan: g6-standard-2, Available: true
❯ go run ./bugcheck/test_region_availability_bug.go
Testing GetRegionAvailability bug...
Calling GetRegionAvailability for region: us-sea
⚠️ Unexpected success - got result: [{Region:us-sea Plan:g6-standard-1 Available:true} {Region:us-sea Plan:g6-standard-2 Available:true} {Region:us-sea Plan:g6-standard-4 Available:true} {Region:us-sea Plan:g6-standard-6 Available:true} {Region:us-sea Plan:g6-standard-8 Available:true} {Region:us-sea Plan:g6-standard-16 Available:true} {Region:us-sea Plan:g6-standard-20 Available:true} {Region:us-sea Plan:g6-standard-24 Available:true} {Region:us-sea Plan:g6-standard-32 Available:true} {Region:us-sea Plan:g6-nanode-1 Available:true} {Region:us-sea Plan:g6-dedicated-2 Available:true} {Region:us-sea Plan:g6-dedicated-4 Available:true} {Region:us-sea Plan:g6-dedicated-8 Available:true} {Region:us-sea Plan:g6-dedicated-16 Available:true} {Region:us-sea Plan:g6-dedicated-32 Available:true} {Region:us-sea Plan:g6-dedicated-48 Available:true} {Region:us-sea Plan:g1-gpu-rtx6000-1 Available:false} {Region:us-sea Plan:g1-gpu-rtx6000-2 Available:false} {Region:us-sea Plan:g1-gpu-rtx6000-3 Available:false} {Region:us-sea Plan:g1-gpu-rtx6000-4 Available:false} {Region:us-sea Plan:g6-dedicated-50 Available:true} {Region:us-sea Plan:g6-dedicated-56 Available:true} {Region:us-sea Plan:g7-highmem-1 Available:true} {Region:us-sea Plan:g7-highmem-2 Available:true} {Region:us-sea Plan:g7-highmem-4 Available:true} {Region:us-sea Plan:g7-highmem-8 Available:true} {Region:us-sea Plan:g7-highmem-16 Available:true} {Region:us-sea Plan:g7-premium-2 Available:true} {Region:us-sea Plan:g7-premium-4 Available:true} {Region:us-sea Plan:g7-premium-8 Available:true} {Region:us-sea Plan:g7-premium-16 Available:true} {Region:us-sea Plan:g7-premium-32 Available:true} {Region:us-sea Plan:g7-premium-48 Available:true} {Region:us-sea Plan:g7-premium-50 Available:true} {Region:us-sea Plan:g7-premium-56 Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a1-s Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a1-m Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a1-l Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a1-xl Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a2-s Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a2-m Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a2-hs Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a4-s Available:true} {Region:us-sea Plan:g2-gpu-rtx4000a4-m Available:true} {Region:us-sea Plan:g1-accelerated-netint-vpu-t1u1-s Available:false} {Region:us-sea Plan:g1-accelerated-netint-vpu-t1u1-m Available:false} {Region:us-sea Plan:g1-accelerated-netint-vpu-t1u2-s Available:false} {Region:us-sea Plan:g8-dedicated-4-2 Available:false} {Region:us-sea Plan:g8-dedicated-8-4 Available:false} {Region:us-sea Plan:g8-dedicated-16-8 Available:false} {Region:us-sea Plan:g8-dedicated-32-16 Available:false} {Region:us-sea Plan:g8-dedicated-64-32 Available:false} {Region:us-sea Plan:g8-dedicated-96-48 Available:false} {Region:us-sea Plan:g8-dedicated-128-64 Available:false} {Region:us-sea Plan:g8-dedicated-256-128 Available:false} {Region:us-sea Plan:g8-dedicated-512-256 Available:false} {Region:us-sea Plan:g8-dedicated-8-2 Available:false} {Region:us-sea Plan:g8-dedicated-16-4 Available:false} {Region:us-sea Plan:g8-dedicated-32-8 Available:false} {Region:us-sea Plan:g8-dedicated-64-16 Available:false} {Region:us-sea Plan:g8-dedicated-96-24 Available:false} {Region:us-sea Plan:g8-dedicated-128-32 Available:false} {Region:us-sea Plan:g8-dedicated-256-64 Available:false} {Region:us-sea Plan:g8-dedicated-512-128 Available:false} {Region:us-sea Plan:g7-dedicated-4-2 Available:true} {Region:us-sea Plan:g7-dedicated-8-4 Available:true} {Region:us-sea Plan:g7-dedicated-16-8 Available:true} {Region:us-sea Plan:g7-dedicated-32-16 Available:true} {Region:us-sea Plan:g7-dedicated-64-32 Available:true} {Region:us-sea Plan:g7-dedicated-96-48 Available:true} {Region:us-sea Plan:g7-dedicated-128-50 Available:true} {Region:us-sea Plan:g7-dedicated-256-56 Available:true}]
This shouldn't work since API returns an array, not a single object
---
For comparison, ListRegionsAvailability works correctly:
✅ Successfully got 72 availability records for region us-sea
First few records:
- Plan: g6-standard-1, Available: true
- Plan: g6-standard-2, Available: true
- Plan: g6-standard-4, Available: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment