rules: - id: acceptance-test-naming-parent-disappears languages: [go] message: Prefer naming acceptance tests with _disappears_Parent suffix paths: include: - "internal/**/*_test.go" patterns: - pattern: func $FUNCNAME(t *testing.T) { ... } - metavariable-regex: metavariable: "$FUNCNAME" regex: "^TestAcc[^_]+_([a-zA-Z]+[dD]isappears|[^_]+_disappears)$" severity: WARNING - id: aws-sdk-go-multiple-service-imports languages: [go] message: Resources should not implement multiple AWS service functionality paths: include: - internal/ exclude: - "internal/service/**/*_test.go" - "internal/service/**/sweep.go" - "internal/acctest/acctest.go" - "internal/conns/**/*.go" patterns: - pattern: | import ("$X") import ("$Y") - metavariable-regex: metavariable: '$X' regex: '^"github.com/aws/aws-sdk-go/service/[^/]+"$' - metavariable-regex: metavariable: '$Y' regex: '^"github.com/aws/aws-sdk-go/service/[^/]+"$' # wafregional uses a number of resources from waf - pattern-not: | import ("github.com/aws/aws-sdk-go/service/waf") import ("github.com/aws/aws-sdk-go/service/wafregional") severity: WARNING - id: prefer-aws-go-sdk-pointer-conversion-assignment languages: [go] message: Prefer AWS Go SDK pointer conversion functions for dereferencing during assignment, e.g. aws.StringValue() paths: include: - internal/service exclude: - "internal/service/**/*_test.go" patterns: - pattern: '$LHS = *$RHS' - pattern-not: '*$LHS2 = *$RHS' severity: WARNING - id: prefer-aws-go-sdk-pointer-conversion-conditional languages: [go] message: Prefer AWS Go SDK pointer conversion functions for dereferencing during conditionals, e.g. aws.StringValue() paths: include: - internal/service exclude: - "internal/service/**/*_test.go" patterns: - pattern-either: - pattern: '$LHS == *$RHS' - pattern: '$LHS != *$RHS' - pattern: '$LHS > *$RHS' - pattern: '$LHS < *$RHS' - pattern: '$LHS >= *$RHS' - pattern: '$LHS <= *$RHS' - pattern: '*$LHS == $RHS' - pattern: '*$LHS != $RHS' - pattern: '*$LHS > $RHS' - pattern: '*$LHS < $RHS' - pattern: '*$LHS >= $RHS' - pattern: '*$LHS <= $RHS' severity: WARNING - id: aws-go-sdk-pointer-conversion-ResourceData-SetId fix: d.SetId(aws.StringValue($VALUE)) languages: [go] message: Prefer AWS Go SDK pointer conversion aws.StringValue() function for dereferencing during d.SetId() paths: include: - internal/ pattern: 'd.SetId(*$VALUE)' severity: WARNING - id: aws-go-sdk-pointer-conversion-immediate-dereference fix: $VALUE languages: [go] message: Using AWS Go SDK pointer conversion, e.g. aws.String(), with immediate dereferencing is extraneous paths: include: - internal/ patterns: - pattern-either: - pattern: '*aws.Bool($VALUE)' - pattern: '*aws.Float64($VALUE)' - pattern: '*aws.Int64($VALUE)' - pattern: '*aws.String($VALUE)' - pattern: '*aws.Time($VALUE)' severity: WARNING - id: data-source-with-resource-read languages: [go] message: Calling a resource's Read method from within a data-source is discouraged paths: include: - internal/service/**/*_data_source.go patterns: - pattern-regex: '(resource.+Read|flatten.+Resource)' - pattern-inside: func $FUNCNAME(...) $RETURNTYPE { ... } - pattern-not-inside: | d.Set(..., []interface{}{ ... }) - pattern-not-inside: | d.Set($ATTRIBUTE, $FUNC($APIOBJECT)) - metavariable-regex: metavariable: "$FUNCNAME" regex: "dataSource.+Read" severity: WARNING - id: helper-acctest-RandInt-compiled languages: [go] message: Using `acctest.RandInt()` in constant or variable declaration will execute during compilation and not randomize, pass into string generating function instead paths: include: - internal/ patterns: - pattern-either: - pattern: const $CONST = fmt.Sprintf(..., <... acctest.RandInt() ...>, ...) - pattern: var $VAR = fmt.Sprintf(..., <... acctest.RandInt() ...>, ...) severity: WARNING - id: helper-acctest-RandString-compiled languages: [go] message: Using `acctest.RandString()` in constant or variable declaration will execute during compilation and not randomize, pass into string generating function instead paths: include: - internal/ patterns: - pattern-either: - pattern: const $CONST = fmt.Sprintf(..., <... acctest.RandString(...) ...>, ...) - pattern: var $VAR = fmt.Sprintf(..., <... acctest.RandString(...) ...>, ...) severity: WARNING - id: helper-acctest-RandomWithPrefix-compiled languages: [go] message: Using `acctest.RandomWithPrefix()` in constant or variable declaration will execute during compilation and not randomize, pass into string generating function instead paths: include: - internal/ patterns: - pattern-either: - pattern: const $CONST = fmt.Sprintf(..., <... acctest.RandomWithPrefix(...) ...>, ...) - pattern: var $VAR = fmt.Sprintf(..., <... acctest.RandomWithPrefix(...) ...>, ...) severity: WARNING - id: helper-schema-Set-extraneous-NewSet-with-flattenStringList languages: [go] message: Prefer `flex.FlattenStringSet()` or `flex.FlattenStringValueSet()` paths: include: - internal/ patterns: - pattern: schema.NewSet(schema.HashString, flex.FlattenStringList($APIOBJECT)) - pattern: schema.NewSet(schema.HashString, flex.FlattenStringValueList($APIOBJECT)) severity: WARNING - id: helper-schema-Set-extraneous-expandStringList-with-List languages: [go] message: Prefer `flex.ExpandStringSet()` or `flex.ExpandStringValueSet()` paths: include: - internal/ patterns: - pattern-either: - pattern: flex.ExpandStringList($SET.List()) - pattern: | $LIST := $SET.List() ... flex.ExpandStringList($LIST) - pattern: flex.ExpandStringValueList($SET.List()) - pattern: | $LIST := $SET.List() ... flex.ExpandStringValueList($LIST) severity: WARNING - id: helper-schema-ResourceData-GetOk-with-extraneous-conditional languages: [go] message: Zero value conditional check after `d.GetOk()` is extraneous paths: include: - internal/ patterns: - pattern-either: - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(bool) { $BODY } - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(int) != 0 { $BODY } - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(int) > 0 { $BODY } - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(string) != "" { $BODY } - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && len($VALUE.(string)) > 0 { $BODY } severity: WARNING - id: helper-schema-ResourceData-Set-extraneous-value-pointer-conversion fix: d.Set($ATTRIBUTE, $APIOBJECT) languages: [go] message: AWS Go SDK pointer conversion function for `d.Set()` value is extraneous paths: include: - internal/ patterns: - pattern-either: - pattern: d.Set($ATTRIBUTE, aws.BoolValue($APIOBJECT)) - pattern: d.Set($ATTRIBUTE, aws.Float64Value($APIOBJECT)) - pattern: d.Set($ATTRIBUTE, aws.IntValue($APIOBJECT)) - pattern: d.Set($ATTRIBUTE, aws.Int64Value($APIOBJECT)) - pattern: d.Set($ATTRIBUTE, int(aws.Int64Value($APIOBJECT))) - pattern: d.Set($ATTRIBUTE, aws.StringValue($APIOBJECT)) severity: WARNING # Not sure why this isn't working # - id: helper-schema-ResourceData-DataSource-Set-tags # languages: [go] # message: (schema.ResourceData).Set() call with the tags key should include IgnoreConfig in the value # paths: # include: # - internal/service/**/*_data_source.go # exclude: # - internal/service/**/*.go # patterns: # - pattern-inside: func $READMETHOD(...) $ERRORTYPE { ... } # - pattern: if err := d.Set("tags", $TAGSMAP); err != nil { ... } # - pattern-not: if err := d.Set("tags", $KEYVALUETAGS.IgnoreAws().IgnoreConfig($CONFIG).Map()); err != nil { ... } # severity: WARNING - id: helper-schema-ResourceData-Resource-Set-tags languages: [go] message: (schema.ResourceData).Set() call with the tags key should be preceded by a call to IgnoreConfig or include IgnoreConfig in the value in the case of ASG paths: include: - internal/service/**/*.go exclude: - internal/service/**/*_data_source.go patterns: - pattern-inside: func $READMETHOD(...) $ERRORTYPE { ... } - pattern-either: - pattern: | tags := $TAGS ... if err := d.Set("tags", $TAGSMAP); err != nil { ... } - pattern: | tags = $TAGS ... if err := d.Set("tags", $TAGSMAP); err != nil { ... } - pattern: | $ASGTAGS := keyvaluetags.AutoscalingKeyValueTags(...) ... if err := d.Set("tags", $TAGSMAP); err != nil { ... } - pattern-not-regex: 'keyvaluetags.AutoscalingKeyValueTags\(.+\).IgnoreAws\(\).IgnoreConfig' - pattern-not: | tags = $KEYVALUETAGS.IgnoreAws().IgnoreConfig($CONFIG) ... - pattern-not: | tags = $KEYVALUETAGS.$IGNORESERVICE().IgnoreConfig($CONFIG) ... - pattern-not: | tags := keyvaluetags.$VALUETAGS($RESOURCETAGS).IgnoreAws().IgnoreConfig($CONFIG) ... - pattern-not: | tags = keyvaluetags.$VALUETAGS($RESOURCETAGS).IgnoreAws().IgnoreConfig($CONFIG) ... - pattern-not: | tags = $VALUETAGS($RESOURCETAGS).IgnoreAWS().IgnoreConfig($CONFIG).Ignore($IGNORE) ... severity: WARNING - id: helper-schema-ResourceData-SetId-empty-without-IsNewResource-check languages: [go] message: Calling `d.SetId("")` should ensure `!d.IsNewResource()` is also checked. See https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/error-handling.md#disnewresource-checks paths: include: - internal/service exclude: - internal/service/**/*_data_source.go - internal/service/backup - internal/service/batch - internal/service/d[a-d]* - internal/service/devicefarm - internal/service/directconnect - internal/service/dlm - internal/service/dms - internal/service/ds - internal/service/dynamodb - internal/service/ec2 - internal/service/ecs - internal/service/efs - internal/service/elasticache - internal/service/elasticbeanstalk - internal/service/elastictranscoder - internal/service/elbv2 - internal/service/emr - internal/service/g* - internal/service/inspector - internal/service/iot - internal/service/kafka - internal/service/kms - internal/service/lambda - internal/service/lexmodels - internal/service/licensemanager - internal/service/lightsail - internal/service/logs - internal/service/macie - internal/service/macie2 - internal/service/mediastore - internal/service/mq - internal/service/neptune - internal/service/opsworks - internal/service/organizations - internal/service/pinpoint - internal/service/rds - internal/service/resourcegroups - internal/service/route53 - internal/service/route53resolver - internal/service/s[a-df-rt]* - internal/service/se[d-z]* - internal/service/sec[a-t]* - internal/service/securityhub - internal/service/ssoadmin - internal/service/swf - internal/service/[t-v]* - internal/service/waf - internal/service/wafv2 - internal/service/workspaces - internal/service/xray patterns: - pattern-either: - pattern: | d.SetId("") ... return nil - pattern-not-inside: | if ... { if <... d.IsNewResource() ...> { ... } ... d.SetId("") ... return nil } - pattern-not-inside: | if <... !d.IsNewResource() ...> { ... } severity: WARNING - id: helper-schema-resource-Retry-without-TimeoutError-check languages: [go] message: Check resource.Retry() errors with tfresource.TimedOut() paths: exclude: - "*_test.go" - sweep.go include: - internal/ patterns: - pattern-either: - patterns: - pattern-either: - pattern: | $ERR := resource.Retry(...) ... return ... - pattern: | $ERR = resource.Retry(...) ... return ... - pattern-not: | $ERR := resource.Retry(...) ... if isResourceTimeoutError($ERR) { ... } ... return ... - pattern-not: | $ERR = resource.Retry(...) ... if isResourceTimeoutError($ERR) { ... } ... return ... - pattern-not: | $ERR := resource.Retry(...) ... if tfresource.TimedOut($ERR) { ... } ... return ... - pattern-not: | $ERR = resource.Retry(...) ... if tfresource.TimedOut($ERR) { ... } ... return ... - patterns: - pattern-either: - pattern: | $ERR := resource.RetryContext(...) ... return ... - pattern: | $ERR = resource.RetryContext(...) ... return ... - pattern-not: | $ERR := resource.RetryContext(...) ... if isResourceTimeoutError($ERR) { ... } ... return ... - pattern-not: | $ERR = resource.RetryContext(...) ... if isResourceTimeoutError($ERR) { ... } ... return ... - pattern-not: | $ERR := resource.RetryContext(...) ... if tfresource.TimedOut($ERR) { ... } ... return ... - pattern-not: | $ERR = resource.RetryContext(...) ... if tfresource.TimedOut($ERR) { ... } ... return ... severity: WARNING - id: helper-schema-TimeoutError-check-doesnt-return-output languages: [go] message: If the resource.Retry(), resource.RetryContext(), or tfresource.RetryContext() function returns a value, ensure the isResourceTimeoutError() check does as well paths: exclude: - "*_test.go" include: - internal/ patterns: - pattern-either: - patterns: - pattern: | if isResourceTimeoutError($ERR) { _, $ERR = $CONN.$FUNC(...) } - pattern-not-inside: | $ERR = resource.Retry(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }) ... if isResourceTimeoutError($ERR) { ... } - pattern-not-inside: | $ERR = resource.RetryContext(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }) ... if isResourceTimeoutError($ERR) { ... } - pattern-not-inside: | $ERR = tfresource.RetryContext(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }, ...) ... if isResourceTimeoutError($ERR) { ... } - patterns: - pattern: | if tfresource.TimedOut($ERR) { _, $ERR = $CONN.$FUNC(...) } - pattern-not-inside: | $ERR = resource.Retry(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }) ... if tfresource.TimedOut($ERR) { ... } - pattern-not-inside: | $ERR = resource.RetryContext(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }) ... if tfresource.TimedOut($ERR) { ... } - pattern-not-inside: | $ERR = tfresource.RetryContext(..., func() *resource.RetryError { ... _, $ERR2 = $CONN.$FUNC(...) ... }, ...) ... if tfresource.TimedOut($ERR) { ... } severity: WARNING - id: is-not-found-error languages: [go] message: Check for resource.NotFoundError errors with tfresource.NotFound() paths: include: - internal/ patterns: - pattern-either: - patterns: - pattern: | var $CAST *resource.NotFoundError ... errors.As($ERR, &$CAST) - pattern-not-inside: | var $CAST *resource.NotFoundError ... errors.As($ERR, &$CAST) ... $CAST.$FIELD - patterns: - pattern: | $X, $Y := $ERR.(*resource.NotFoundError) severity: WARNING - id: time-equality languages: [go] message: Use time.Equal() instead of == paths: include: - internal/ patterns: - pattern-either: - pattern: | aws.TimeValue($X) == $Y - pattern: | aws.TimeValue($X) != $Y - pattern: | ($X : time.Time) == $Y - pattern: | ($X : time.Time) != $Y - pattern: | $X == aws.TimeValue($Y) - pattern: | $X != aws.TimeValue($Y) - pattern: | $X == ($Y : time.Time) - pattern: | $X != ($Y : time.Time) severity: WARNING - id: prefer-pagination-bool-var-last-page languages: [go] message: Use lastPage for bool variable in pagination functions paths: include: - internal/ patterns: - pattern: | $X.$Z(..., func(..., $Y bool) { ... }) - pattern-not: | $X.$Z(..., func(..., lastPage bool) { ... }) - pattern-not: | $X.$Z(..., func(..., _ bool) { ... }) - metavariable-regex: metavariable: '$Z' regex: '.*Pages$' severity: WARNING - id: calling-fmt.Print-and-variants languages: [go] message: Do not call `fmt.Print` and variant paths: include: - internal/ exclude: - .ci/providerlint/vendor/ - internal/generate/ patterns: - pattern-either: - pattern: | fmt.Print(...) - pattern: | fmt.Printf(...) - pattern: | fmt.Println(...) severity: WARNING - id: domain-names languages: [go] message: Domain names should be in the namespaces defined in RFC 6761 (https://datatracker.ietf.org/doc/html/rfc6761) as reserved for testing paths: include: - internal/service exclude: - internal/service/firehose/delivery_stream_test.go - internal/service/fsx/windows_file_system_test.go - internal/service/iam/openid_connect_provider_test.go - internal/service/mq/broker_test.go - internal/service/mq/forge_test.go - internal/service/route53/sweep.go - internal/service/s3/bucket_test.go - internal/service/s3/object_test.go - internal/service/storagegateway/cached_iscsi_volume.go - internal/service/storagegateway/cached_iscsi_volume_test.go - internal/service/storagegateway/stored_iscsi_volume_test.go - internal/service/transfer/access_test.go - internal/service/transfer/server_test.go - "internal/service/**/*_test.go" patterns: - patterns: - pattern-regex: '(([-a-zA-Z0-9]{2,}\.)|(%[sdftq]))+(com|net|org)\b' - pattern-inside: '($X : string)' - pattern-not-regex: 'amazonaws\.com' - pattern-not-regex: 'awsapps\.com' - pattern-not-regex: '@(([-a-zA-Z0-9]{2,}\.)|(%[sdftq]))+(com|net|org)\b' # exclude domain names in email addresses - pattern-not-regex: '[^-a-zA-Z0-9]example\.com' - pattern-not-regex: '[^-a-zA-Z0-9]example\.net' - pattern-not-regex: '[^-a-zA-Z0-9]example\.org' - pattern-not-regex: 'github\.com' - pattern-not-regex: 'aws\.amazon\.com' - pattern-not-regex: 'graph\.facebook\.com' - pattern-not-regex: 'people\.googleapis\.com' - pattern-not-regex: 'www\.googleapis\.com' - pattern-not-regex: 'accounts\.google\.com' - pattern-not-regex: '[-a-z0-9]+\.apps\.googleusercontent\.com' - pattern-not-regex: 'elasticbeanstalk\.com' - pattern-not-regex: 'awsglobalaccelerator\.com' - pattern-not-regex: 'cloudfront\.net' - pattern-not-regex: 'http://json-schema\.org/draft-0\d/schema' - pattern-not-regex: 'http://activemq.apache.org/schema/core' - pattern-not-regex: 'mcr.microsoft.com' severity: WARNING - id: email-address languages: [go] message: Use default email address or generate a random email address. https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/running-and-writing-acceptance-tests.md#hardcoded-email-addresses paths: include: - internal/ exclude: - internal/service/route53domains/registered_domain_test.go patterns: - pattern-regex: '[-_A-Za-z0-9.+]+@([-A-Za-z0-9]+\.)(com|net|org)' - pattern-not-regex: 'no-reply@hashicorp\.com' - pattern-inside: '($X : string)' severity: WARNING - id: ssh-key languages: [go] message: Generate random SSH keys using acctest.RandSSHKeyPair() or RandSSHKeyPairSize(). https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/running-and-writing-acceptance-tests.md#hardcoded-ssh-key paths: include: - internal/ exclude: - .ci/providerlint/vendor/ patterns: # This isn't technically the correct regex, but for some reason adding a '+' causes the regex to # miss some SSH keys. AFAICT, this is good enough. - pattern-regex: 'ssh-rsa [A-Za-z0-9/]+' - pattern-inside: '($X : string)' severity: WARNING - id: non-tags-change-detection languages: [go] message: Incorrect form of non-tags change detection. https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/contribution-checklists.md#resource-tagging-code-implementation paths: include: - internal/ patterns: - pattern: 'if d.HasChangeExcept("tags_all") {...}' severity: WARNING - id: unnecessary-literal-type-conversion languages: [go] message: Literal numbers do not need type conversions paths: include: - internal/ patterns: - pattern: "aws.Int64(int64($X))" - metavariable-regex: metavariable: $X regex: (\d+) severity: ERROR fix: "aws.Int64($X)" - id: calling-SetId-with-empty-string-in-resource-create languages: [go] message: Do not call `d.SetId("")` inside a resource create function paths: include: - internal/service/ patterns: - pattern: | func $FUNC(...) { ... d.SetId("") } - metavariable-regex: metavariable: "$FUNC" regex: "^resource\\w*(Create|Put|Set|Upsert|Enable)$" severity: WARNING - id: calling-SetId-with-empty-string-in-resource-update languages: [go] message: Do not call `d.SetId("")` inside a resource update function paths: include: - internal/service/ patterns: - pattern: | func $FUNC(...) { ... d.SetId("") } - metavariable-regex: metavariable: "$FUNC" regex: "^resource\\w*(Update)$|^update\\w*$" # Put and Upsert variants are handled in calling-SetId-with-empty-string-in-resource-create above severity: WARNING - id: calling-SetId-in-resource-delete languages: [go] message: Do not call `d.SetId(...)` inside a resource delete function paths: include: - internal/service/ patterns: - pattern: | func $FUNC(...) { ... d.SetId(...) } - metavariable-regex: metavariable: "$FUNC" regex: "^resource\\w*(Delete|Disable)$" severity: WARNING - id: avoid-string-is-empty-validation languages: [go] message: Empty strings should not be included in validation paths: include: - internal/ patterns: - pattern: validation.Any(..., validation.StringIsEmpty, ...) severity: ERROR - id: use-error-code-equals-if-not-checking-message languages: [go] message: Use tfawserr.ErrCodeEquals() when message parameter is empty string paths: include: - internal/ patterns: - pattern: tfawserr.ErrMessageContains(err, ..., "") severity: ERROR - id: avoid-dependency-for-one-constant languages: [go] message: Use constant in the same package rather than importing iam for a constant paths: include: - internal/ exclude: - internal/service/iam patterns: - pattern: tfiam.PropagationTimeout severity: ERROR - id: use-acctest-protov5-provider-factories languages: [go] message: Use acctest.ProtoV5ProviderFactories, not acctest.Providers or acctest.ProviderFactories paths: include: - "internal/**/*_test.go" pattern-either: - pattern-regex: Providers:\s+(acctest\.)?Providers, - pattern-regex: ProviderFactories:\s+(acctest\.)?ProviderFactories, severity: WARNING - id: prefer-aws-go-sdk-pointer-conversion-int-conversion-int64-pointer fix: $VALUE languages: [go] message: Prefer AWS Go SDK pointer conversion functions for dereferencing when converting int64 to int paths: include: - internal/ pattern: int(*$VALUE) severity: WARNING - id: aws-go-sdk-error-code-helper languages: [go] message: 'Use `tfawserr` helpers for checking AWS Go SDK errors (e.g. `tfawserr.ErrMessageContains(err, CODE, MESSAGE)`)' paths: include: - internal/ patterns: - pattern-either: - pattern: if $AWSERR, $OK := $ORIGINALERR.(awserr.Error); $OK && $AWSERR.Code() == $CODE { $BODY } - pattern: | if $AWSERR, $OK := $ORIGINALERR.(awserr.Error); $OK { if $AWSERR.Code() == $CODE { $BODY } } severity: WARNING - id: fmt-Errorf-awserr-Error-Code languages: [go] message: Prefer `err` with `%w` format verb instead of `err.Code()` or `err.Message()` paths: include: - internal/ patterns: - pattern-either: - pattern: fmt.Errorf(..., $ERR.Code(), ...) - pattern: fmt.Errorf(..., $ERR.Message(), ...) severity: WARNING - id: typed-enum-conversion languages: [go] message: Prefer using `enum.Slice()` to convert a slice of typed string enums to a slice of strings paths: include: - internal/ patterns: - pattern: "[]string{..., string($X), ...}" severity: WARNING - id: avoid-context-TODO-in-tests languages: [go] message: Prefer using context.Background() instead of context.TODO() paths: include: - "internal/**/*_test.go" patterns: - pattern: context.TODO severity: ERROR - id: avoid-context-CRUD-handlers languages: [go] message: Prefer using WithoutTimeout CRUD handlers instead of Context variants paths: include: - internal/service patterns: - pattern-regex: '(Create|Read|Update|Delete)Context:' severity: ERROR