{"record":{"id":"612d109e26586d61","repo":"windmill-labs/windmill","slug":"string-res-body","errorCode":null,"errorMessage":"string(res.Body)","messagePattern":"string\\(res\\.Body\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go-client/windmill.go","lineNumber":51,"sourceCode":"\t\tClient:    client,\n\t\tWorkspace: workspace,\n\t}, nil\n}\nfunc newBool(b bool) *bool {\n\treturn &b\n}\n\nfunc GetVariable(path string) (string, error) {\n\tclient, err := GetClient()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tres, err := client.Client.GetVariableValueWithResponse(context.Background(), client.Workspace, path, &api.GetVariableValueParams{})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif res.StatusCode()/100 != 2 {\n\t\treturn \"\", errors.New(string(res.Body))\n\t}\n\treturn *res.JSON200, nil\n}\n\nfunc GetResource(path string) (interface{}, error) {\n\tclient, err := GetClient()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparams := api.GetResourceValueInterpolatedParams{}\n\tres, err := client.Client.GetResourceValueInterpolatedWithResponse(context.Background(), client.Workspace, path, &params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif res.StatusCode()/100 != 2 {\n\t\treturn nil, errors.New(string(res.Body))\n\t}\n\treturn *res.JSON200, nil","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/go-client/windmill.go#L33-L69","documentation":"GetVariable fetches a Windmill variable's decrypted value. When the HTTP response status is not 2xx, the go client surfaces the raw response body (string(res.Body)) as the error message. The text you see is whatever the Windmill API returned — e.g. a JSON error body describing 404 variable not found or 403 forbidden.","triggerScenarios":"windmill.GetVariable(ctx, path) hitting the API and receiving a non-2xx status: variable does not exist at the given path, the workspace is wrong, or the caller's token lacks read permission on the variable.","commonSituations":"Typo in the variable path; running locally with a token scoped to a different workspace; variables requiring elevated permissions the token doesn't have; deleted/renamed variables after refactoring.","solutions":["Read the returned body (it contains the API's JSON error, e.g. 404 'Variable not found') and fix the path accordingly","Verify the workspace in GetClient() matches where the variable lives","Check that the API token/worker context has permission to read that variable","Use the Windmill UI or `wmill variable list` to confirm the exact path"],"exampleFix":"// before\nv, _ := windmill.GetVariable(context.Background(), \"secrets/api_key\")\n// after\nv, err := windmill.GetVariable(context.Background(), \"secrets/api_key\")\nif err != nil {\n    log.Fatalf(\"get variable: %v\", err) // body reveals 404/403 detail\n}","handlingStrategy":"try-catch","validationCode":"// validate the variable path format before calling\nif path == \"\" || !strings.HasPrefix(path, \"/\") && !strings.HasPrefix(path, \"u/\") && !strings.HasPrefix(path, \"f/\") {\n    return fmt.Errorf(\"invalid variable path: %q\", path)\n}","typeGuard":"func isNotFoundVarErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"not found\")\n}","tryCatchPattern":"v, err := windmill.GetVariable(ctx, path)\nif err != nil {\n    if strings.Contains(err.Error(), \"404\") || strings.Contains(err.Error(), \"not found\") {\n        // handle missing variable (create it, use default)\n    } else if strings.Contains(err.Error(), \"403\") || strings.Contains(err.Error(), \"permission\") {\n        // handle access denied\n    }\n    return err\n}","preventionTips":["Always check the error from GetVariable — the body names the exact status/cause","Confirm the workspace and path in the Windmill UI before coding against them","Use least-privilege tokens with variable read grants","Centralize variable paths in constants to avoid typos"],"tags":["go","windmill","http-error","api-response"],"backgroundTag":"http-non-2xx-error-body","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}