{"record":{"id":"51522a69f8ba4fb1","repo":"hashicorp/terraform","slug":"q-attribute-is-read-only","errorCode":null,"errorMessage":"%q attribute is read-only","messagePattern":"%q attribute is read-only","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/providers/terraform/resource_data.go","lineNumber":89,"sourceCode":"\t\t\t\t\tDescription: \"The unique identifier for the data store.\",\n\t\t\t\t\tRequired:    true,\n\t\t\t\t},\n\t\t\t},\n\t\t\tNesting: configschema.NestingSingle,\n\t\t},\n\t}\n}\n\nfunc validateDataStoreResourceConfig(req providers.ValidateResourceConfigRequest) (resp providers.ValidateResourceConfigResponse) {\n\tif req.Config.IsNull() {\n\t\treturn resp\n\t}\n\n\t// Core does not currently validate computed values are not set in the\n\t// configuration.\n\tfor _, attr := range []string{\"id\", \"output\"} {\n\t\tif !req.Config.GetAttr(attr).IsNull() {\n\t\t\tresp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf(`%q attribute is read-only`, attr))\n\t\t}\n\t}\n\treturn resp\n}\n\nfunc upgradeDataStoreResourceState(req providers.UpgradeResourceStateRequest) (resp providers.UpgradeResourceStateResponse) {\n\t// We've only added new nullable block attributes, so unmarshaling from json\n\t// will complete the data structure correctly.\n\tval, err := ctyjson.Unmarshal(req.RawStateJSON, dataStoreResourceSchema().Body.ImpliedType())\n\tif err != nil {\n\t\tresp.Diagnostics = resp.Diagnostics.Append(err)\n\t\treturn resp\n\t}\n\n\tresp.UpgradedState = val\n\treturn resp\n}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/builtin/providers/terraform/resource_data.go#L71-L107","documentation":"Returned by validateDataStoreResourceConfig at resource_data.go:89 when validating a terraform_data data resource. Core does not currently reject computed attributes set in config, so this provider explicitly checks the 'id' and 'output' attributes and reports each as read-only. 'output' is the computed result of terraform_data and 'id' is its computed identity; neither may be supplied by the user.","triggerScenarios":"A terraform_data block whose body sets output = ... or id = ... (e.g. data \"terraform_data\" \"x\" { id = \"abc\" }).","commonSituations":"Copy-pasting a managed-resource pattern into terraform_data; trying to feed a known output back in; assuming id is settable like on some resources.","solutions":["Remove the id and/or output attributes from the data \"terraform_data\" block; both are computed.","If you need to pass input, use the input attribute (arbitrary value) of terraform_data."],"exampleFix":"// before\ndata \"terraform_data\" \"example\" {\n  input = local.value\n  id    = \"fixed-id\"\n}\n\n// after\ndata \"terraform_data\" \"example\" {\n  input = local.value\n}","handlingStrategy":"validation","validationCode":"// Before applying, lint terraform_data blocks for settable computed attrs.\nvar dataBlocks []cty.Value // parsed config blocks of terraform_data\nreadOnly := map[string]bool{\"id\": true, \"output\": true}\nfor _, b := range dataBlocks {\n    for attr := range readOnly {\n        if v := b.GetAttr(attr); !v.IsNull() {\n            return fmt.Errorf(\"terraform_data: %q is read-only\", attr)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat terraform_data like a passthrough: only set 'input'.","Add a terraform validate step to CI to catch read-only attribute errors before apply."],"tags":["terraform","terraform-data","config-validation","read-only"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}