{"record":{"id":"8d08e920828dc37a","repo":"kubernetes/kops","slug":"error-parsing-expected-rolepolicydocument-for-iamr","errorCode":null,"errorMessage":"error parsing expected RolePolicyDocument for IAMRole %q: %v","messagePattern":"error parsing expected RolePolicyDocument for IAMRole %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":103,"sourceCode":"\tif r.AssumeRolePolicyDocument != nil {\n\t\t// The AssumeRolePolicyDocument is URI encoded (?)\n\t\tactualPolicy := *r.AssumeRolePolicyDocument\n\t\tactualPolicy, err = url.QueryUnescape(actualPolicy)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing AssumeRolePolicyDocument for IAMRole %s: %v\", *e.Name, err)\n\t\t}\n\n\t\t// The RolePolicyDocument is reformatted by AWS\n\t\t// We parse both as JSON; if the json forms are equal we pretend the actual value is the expected value\n\t\tif e.RolePolicyDocument != nil {\n\t\t\texpectedPolicy, err := fi.ResourceAsString(e.RolePolicyDocument)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error reading expected RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\t\t\texpectedJson := make(map[string]interface{})\n\t\t\terr = json.Unmarshal([]byte(expectedPolicy), &expectedJson)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing expected RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\t\t\tactualJson := make(map[string]interface{})\n\t\t\terr = json.Unmarshal([]byte(actualPolicy), &actualJson)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing actual RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\n\t\t\tif reflect.DeepEqual(actualJson, expectedJson) {\n\t\t\t\tklog.V(2).Infof(\"actual RolePolicyDocument was json-equal to expected; returning expected value\")\n\t\t\t\tactualPolicy = expectedPolicy\n\t\t\t}\n\t\t}\n\n\t\tactual.RolePolicyDocument = fi.NewStringResource(actualPolicy)\n\t}\n\tactual.Tags = mapIAMTagsToMap(r.Tags)\n\n\tklog.V(2).Infof(\"found matching IAMRole %q\", aws.ToString(actual.ID))","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L85-L121","documentation":"Find() parses the expected RolePolicyDocument as JSON so it can compare semantically against the actual policy. If the expected content is not valid JSON, the parse error is wrapped with the role name. This is a spec/template problem, not an AWS problem.","triggerScenarios":"json.Unmarshal([]byte(expectedPolicy), &expectedJson) fails because the template produced invalid JSON (trailing commas, comments, unquoted keys, truncated output).","commonSituations":"Hand-edited trust policy template in the cluster spec; Go template placeholders left unresolved; kOps version mismatch generating malformed policy; file truncated in state store.","solutions":["Validate the policy JSON locally (jq . policy.json) before applying the cluster spec","Fix the template or manifest producing the invalid JSON (remove comments/commas, ensure variables resolve)","Regenerate the manifest with kops replace/update using a known-good template","Pin the kops version to one consistent with the stored cluster spec"],"exampleFix":"// before (invalid JSON with comment)\n{\"Version\":\"2012-10-17\" /* comment */}\n// after\n{\"Version\":\"2012-10-17\"}","handlingStrategy":"validation","validationCode":"// lint expected policy JSON before apply\nvar buf map[string]interface{}\nif err := json.Unmarshal([]byte(expectedPolicy), &buf); err != nil {\n    return fmt.Errorf(\"expected RolePolicyDocument is not valid JSON: %w\", err)\n}","typeGuard":"func isJSON(s string) bool { var v interface{}; return json.Unmarshal([]byte(s), &v) == nil }","tryCatchPattern":null,"preventionTips":["Run jq/jsonlint on policy templates before kops update","Avoid comments and trailing commas in policy templates","Ensure template variables resolve to real values","Store policies as .json files validated in CI"],"tags":["aws","iam","json","policy","validation"],"backgroundTag":"invalid-json-policy","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}