Last active
February 18, 2026 00:57
-
-
Save glennpratt/e427a03cb749ccec3c3041c6e6396aea to your computer and use it in GitHub Desktop.
Linodego bug check
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
| 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)) | |
| } | |
| } | |
| } |
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
| ❯ 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 |
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
| ❯ 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