{"record":{"id":"a99d2e05bf59edbc","repo":"hashicorp/terraform","slug":"joined-api-error-payload","errorCode":null,"errorMessage":"{joined API error payload}","messagePattern":"\\{joined API error payload\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend_common.go","lineNumber":749,"sourceCode":"\t\treturn nil\n\t}\n\n\tvar errs []string\n\tvar err error\n\n\tswitch r.StatusCode {\n\tcase 401:\n\t\treturn tfe.ErrUnauthorized\n\tcase 404:\n\t\treturn tfe.ErrResourceNotFound\n\t}\n\n\terrs, err = decodeErrorPayload(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn errors.New(strings.Join(errs, \"\\n\"))\n}\n\nfunc decodeErrorPayload(r *http.Response) ([]string, error) {\n\t// Decode the error payload.\n\tvar errs []string\n\terrPayload := &jsonapi.ErrorsPayload{}\n\terr := json.NewDecoder(r.Body).Decode(errPayload)\n\tif err != nil || len(errPayload.Errors) == 0 {\n\t\treturn errs, errors.New(r.Status)\n\t}\n\n\t// Parse and format the errors.\n\tfor _, e := range errPayload.Errors {\n\t\tif e.Detail == \"\" {\n\t\t\terrs = append(errs, e.Title)\n\t\t} else {\n\t\t\terrs = append(errs, fmt.Sprintf(\"%s\\n\\n%s\", e.Title, e.Detail))\n\t\t}","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/cloud/backend_common.go#L731-L767","documentation":"Generic error assembled by checkResponseCode() in the cloud backend for any non-2xx HTTP response that is not 401/404: decodeErrorPayload() reads the JSON:API errors array and this site joins each error's Title (+Detail) with newlines into one error string. The literal message is whatever the HCP/TFE API returned.","triggerScenarios":"Any HCP/TFE API call (readRedactedPlan, run/state APIs, etc.) returning 4xx/5xx with a parseable JSON:API error body — e.g. 422 validation errors, 500 server errors, 409 conflicts.","commonSituations":"Invalid workspace name; run conflicts; plan output no longer available; quota exceeded; backend-side validation failure surfaced as multiple JSON:API errors.","solutions":["Read the joined Title/Detail lines — they carry the backend's specific reason.","Address the underlying API error (fix the referenced resource/config), then retry.","If the error is a transient 5xx, retry with backoff; consult HCP/TFE status.","For 4xx, verify workspace/org/permissions and the request payload."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := b.client.Workspaces.Read(ctx, org, name)\nif err != nil {\n    // err is a joined string of JSON:API Title/Detail lines;\n    // classify by known substrings or re-parse for structured handling.\n    if strings.Contains(err.Error(), \"not found\") {\n        // handle missing workspace\n    }\n    return err\n}","preventionTips":["Surface the full joined Title/Detail text to users — it is the backend's reason.","Use TF_LOG=TRACE during debugging to see the raw API response.","Retry only transient (5xx/conflict) classes; fix 4xx at the source."],"tags":["terraform","cloud-backend","hcp","tfe","api","http"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}