500 errors encountered when using GraphQL Mutation.epicAddIssue

Summary

500 error is encountered when using Mutation.epicAddIssue GraphQL call on issues with the following attributes

  • A non-confidential issue linked to a confidential epic.
  • An issue that's already been linked to an epic.
  • An issue belonging to a project in a different namespace from the epic being linked.

Steps to reproduce

  • A non-confidential issue linked to a confidential epic:

    1. Create a new, non-confidential issue in a project under the gitlab-org namespace, such as https://gitlab.com/gitlab-org/secure/scratch/-/issues/new

    2. Attempt to link the newly created non-confidential issue, for example gitlab-org/secure/scratch#1, to a confidential epic using Mutation.epicAddIssue:

      mutation {
        epicAddIssue(input: {
          iid: "8929"
          issueIid: "1"
          groupPath: "gitlab-org"
          projectPath: "gitlab-org/secure/scratch"
        })
        {
          errors
        }
      }

      ERROR: Internal server error is returned:

      {
        "errors": [
          {
            "message": "Internal server error"
          }
        ]
      }
  • An issue that's already been linked to an epic:

    1. Create a new, confidential issue in a project under the gitlab-org namespace, such as https://gitlab.com/gitlab-org/secure/scratch/-/issues/new

    2. Link the newly created issue, for example https://gitlab.com/gitlab-org/secure/scratch/-/issues/2, to an epic using Mutation.epicAddIssue:

      mutation {
        epicAddIssue(input: {
          iid: "8929"
          issueIid: "2"
          groupPath: "gitlab-org"
          projectPath: "gitlab-org/secure/scratch"
        })
        {
          errors
        }
      }

      Issue is linked as expected:

      {
        "data": {
          "epicAddIssue": {
            "errors": []
          }
        }
      }
    3. Execute the above call a second time:

      mutation {
        epicAddIssue(input: {
          iid: "8929"
          issueIid: "2"
          groupPath: "gitlab-org"
          projectPath: "gitlab-org/secure/scratch"
        })
        {
          errors
        }
      }

      ERROR: Internal server error is returned:

      {
        "errors": [
          {
            "message": "Internal server error"
          }
        ]
      }
  • An issue belonging to a project in a different namespace from the epic being linked.

    1. Create an issue in a project with a personal namespace, for example: https://gitlab.com/adamcohen/379246-trivy-cvss-source-info/-/issues/1

    2. Attempt to link the newly created issue, to an epic in another parent namespace using Mutation.epicAddIssue:

      mutation {
        epicAddIssue(input: {
          iid: "8929"
          issueIid: "1"
          groupPath: "gitlab-org"
          projectPath: "379246-trivy-cvss-source-info"
        })
        {
          errors
        }
      }

      ERROR: Internal server error is returned:

      {
        "errors": [
          {
            "message": "Internal server error"
          }
        ]
      }

Example Project

https://gitlab.com/gitlab-org/secure/scratch/

What is the current bug behavior?

GraphQL returns "message": "Internal server error"

What is the expected correct behavior?

GraphQL should return more descriptive error messages when dealing with issues having the following attributes:

  • A non-confidential issue linked to a confidential epic.

    Error message should be: "#1 (closed) cannot be added: Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"

  • An issue that's already been linked to an epic.

    Error message should be: "#1 (closed) cannot be added: Epic has already been assigned to the issue."

Possible fixes

The following error message is output in the logs for each for the above situations:

Internal server error: undefined method `to_a' for #<String:0x00007f82eb8c1098>
Did you mean?  to_d

/path/to/gdk-ee/gitlab/lib/gitlab/graphql/authorize/connection_filter_extension.rb:55:in `after_resolve'

If we look at lib/gitlab/graphql/authorize/connection_filter_extension.rb:54, we see:

redact_list(value.to_a, context) unless value.nil?

In each of the the above cases, value is equal to a string representing the error message:

  • A non-confidential issue linked to a confidential epic.

    1 cannot be added: Cannot assign a confidential epic to a non-confidential issue.
    Make the issue confidential and try again`, and using `to_a` on the string causes an error.
  • An issue that's already been linked to an epic.

    Issue(s) already assigned
  • An issue belonging to a project in a different namespace from the epic being linked.

    No matching issue found. Make sure that you are adding a valid issue URL.

So the error is caused by trying to execute to_a on a string.

Executing to_a used to work on ruby 1.8.7, because the string included the Enumerable module, however, this behaviour changed in ruby 1.9.3, and using to_a on a string will now result in an error.

Edited by Adam Cohen