{"record":{"id":"abcc5a674b4176ae","repo":"gitlabhq/gitlabhq","slug":"value-inspect-is-not-a-gitlab-global-id","errorCode":null,"errorMessage":"#{value.inspect} is not a Gitlab Global ID","messagePattern":"#(.+?) is not a Gitlab Global ID","errorType":"exception","errorClass":"GraphQL::CoercionError","httpStatus":null,"severity":"error","filePath":"app/graphql/types/global_id_type.rb","lineNumber":32,"sourceCode":"      `1` is the record id as per the id in the db table.\n\n      Global identifiers are encoded as strings.\n    DESC\n\n    # @param value [GID]\n    # @return [String]\n    def self.coerce_result(value, _ctx)\n      ::Gitlab::GlobalId.as_global_id(value).to_s\n    end\n\n    # @param value [String]\n    # @return [GID]\n    def self.coerce_input(value, _ctx)\n      return if value.nil?\n\n      gid = GlobalID.parse(value)\n      raise GraphQL::CoercionError, \"#{value.inspect} is not a valid Global ID\" if gid.nil?\n      raise GraphQL::CoercionError, \"#{value.inspect} is not a Gitlab Global ID\" unless gid.app == GlobalID.app\n\n      gid\n    end\n\n    # Construct a restricted type, that can only be inhabited by an ID of\n    # a given model class.\n    def self.[](model_class)\n      @id_types ||= {\n        # WorkItem has a special class as we want to allow IssueID\n        # on WorkItemID while we transition into work items\n        ::WorkItem => ::Types::WorkItemIdType\n      }\n\n      @id_types[model_class] ||= Class.new(self) do\n        model_name = model_class.name\n\n        graphql_name model_name_to_graphql_name(model_name)\n        description <<~MD.strip","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/gitlabhq/gitlabhq/blob/55ee20384a1f55cb0e362dee1d07149613b1b9bf/app/graphql/types/global_id_type.rb#L14-L50","documentation":"Types::GlobalIDType.coerce_input (app/graphql/types/global_id_type.rb:32) raises GraphQL::CoercionError when the string parses as a Global ID but its app segment differs from GlobalID.app (i.e. anything other than \"gitlab\"). So \"gid://other-app/Issue/1\" is well-formed but foreign, and GitLab rejects it to prevent cross-application id confusion.","triggerScenarios":"Passing a Global ID minted by another Rails app (gid://my-app/User/1) or a hand-typed gid with a wrong app segment (gid://github/Issue/1) to any GitLab ID argument.","commonSituations":"Shared libraries that serialize GlobalIDs from multiple apps; copy-paste from tutorials using placeholder apps; environments where GlobalID.app was customized on the producing side.","solutions":["Rebuild the id with the gitlab app: \"gid://gitlab/#{gid.model_name}/#{gid.model_id}\".","If producing ids in Ruby, use the model's to_global_id (which uses the app configured in this Rails app).","Audit producers/consumers so only gitlab-app gids flow into the GitLab GraphQL API."],"exampleFix":"# before\n{\"id\": \"gid://foo-app/Issue/1\"}\n\n# after\n{\"id\": \"gid://gitlab/Issue/1\"}","handlingStrategy":"type-guard","validationCode":"const ok = /^gid:\\/\\/gitlab\\//.test(id);\nif (!ok) throw new RangeError('Global ID must use the gitlab app segment');","typeGuard":"function isGitlabAppGid(s) { return typeof s === 'string' && s.startsWith('gid://gitlab/'); }","tryCatchPattern":null,"preventionTips":["Produce gids only via to_global_id (or the documented gid://gitlab/ prefix).","Do not feed GlobalIDs minted by other Rails apps into GitLab's API.","Validate the app segment when ids arrive from external systems."],"tags":["graphql","global-id","scalar-coercion","argument-validation"],"backgroundTag":"invalid-global-id","analyzedSha":"55ee20384a1f55cb0e362dee1d07149613b1b9bf","analyzedAt":"2026-08-21T14:22:27.782Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}