Skip to content

GitHub GrapQL api requests are triggered with wrong auth on edge case #1039

Description

@notaphplover

Given the following global config:

{
  "$schema": "https://docs.renovatebot.com/renovate-global-schema.json",
  "allowedCommands": ["pnpm dlx @fission-ai/openspec update"],
  "binarySource": "install"
}

Given the following config:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "automerge": false,
  "customManagers": [
    {
      "customType": "regex",
      "description": "Update @fission-ai/openspec version tracked via generatedBy field in skill files",
      "managerFilePatterns": ["/^\\.agent/skills/[^/]+/SKILL\\.md$/"],
      "matchStrings": ["generatedBy:\\s*\"(?<currentValue>[^\"]+)\""],
      "depNameTemplate": "@fission-ai/openspec",
      "datasourceTemplate": "npm",
      "versioningTemplate": "npm"
    },
    {
      "customType": "regex",
      "description": "Update node version tracked in package.json engines field",
      "managerFilePatterns": ["/(^|/)package\\.json$/"],
      "matchStrings": [
        "\"devEngines\"\\s*:\\s*\\{[\\s\\S]*?\"node\"\\s*:\\s*\"(?<currentValue>[^\"]+)\""
      ],
      "depNameTemplate": "node",
      "datasourceTemplate": "node-version"
    },
    {
      "customType": "regex",
      "description": "Update pnpm version tracked in package.json engines field",
      "managerFilePatterns": ["/(^|/)package\\.json$/"],
      "matchStrings": [
        "\"devEngines\"\\s*:\\s*\\{[\\s\\S]*?\"pnpm\"\\s*:\\s*\"(?<currentValue>[^\"]+)\""
      ],
      "depNameTemplate": "pnpm",
      "datasourceTemplate": "npm"
    },
    {
      "customType": "regex",
      "description": "Update uWebSockets.js version tracked in package.json dependencies",
      "managerFilePatterns": ["/(^|/)package\\.json$/"],
      "matchStrings": [
        "uNetworking/uWebSockets\\.js#(?<currentValue>[^\"\\s]+)"
      ],
      "depNameTemplate": "uNetworking/uWebSockets.js",
      "datasourceTemplate": "github-tags",
      "versioningTemplate": "semver-coerced"
    }
  ],
  "constraints": { "pnpm": "11.5.2" },
  "extends": [
    ":dependencyDashboard",
    ":disableRateLimiting",
    ":semanticCommitScopeDisabled",
    ":semanticPrefixFixDepsChoreOthers",
    "group:monorepos",
    "group:recommended",
    "helpers:pinGitHubActionDigests",
    "mergeConfidence:age-confidence-badges",
    "replacements:all",
    "workarounds:all"
  ],
  "ignoreDeps": [],
  "ignorePaths": [
    "**/node_modules/**",
    "**/bower_components/**",
    "**/vendor/**",
    "**/__tests__/**",
    "**/test/**",
    "**/tests/**",
    "**/__fixtures__/**"
  ],
  "packageRules": [
    {
      "description": "Ignore updates to dependencies that are less than 3 days old",
      "matchDatasources": ["npm"],
      "minimumReleaseAge": "3 days"
    },
    {
      "enabled": false,
      "matchDepTypes": ["peerDependencies"],
      "matchPackageNames": ["express"],
      "matchUpdateTypes": ["major"],
      "matchCurrentVersion": ">=4.0.0 <5.0.0"
    },
    {
      "enabled": false,
      "matchPackageNames": ["@types/express"],
      "matchUpdateTypes": ["major"],
      "matchCurrentVersion": ">=4.0.0 <5.0.0"
    },
    {
      "automerge": true,
      "description": "auto merge on patch or minor",
      "groupName": "auto merge on patch or minor",
      "matchUpdateTypes": ["patch", "minor"],
      "matchPackageNames": ["!turbo", "!typescript"]
    },
    {
      "description": "Group GitHub Actions updates",
      "groupName": "GitHub Actions",
      "matchManagers": ["github-actions"]
    },
    {
      "description": "Quarantine packages with current known issues",
      "enabled": false,
      "matchPackageNames": []
    },
    {
      "description": "Ignore inversify version-aliased dependencies (e.g. inversify6, inversify7)",
      "enabled": false,
      "matchPackageNames": ["/^inversify\\d+$/"]
    },
    {
      "description": "Regenerate OpenSpec instruction files after @fission-ai/openspec is bumped",
      "matchPackageNames": ["@fission-ai/openspec"],
      "postUpgradeTasks": {
        "commands": ["pnpm dlx @fission-ai/openspec update"],
        "executionMode": "branch",
        "fileFilters": ["**/skills/**"],
        "installTools": {
          "node": {},
          "pnpm": {}
        }
      }
    }
  ],
  "rangeStrategy": "bump",
  "rebaseWhen": "conflicted",
  "semanticCommits": "enabled",
  "schedule": ["at any time"]
}

I've been trying to use the action to bump dependencies so I can allow custom commands and have post upgrade tasks.
The action receives a Github token with enough permissions, but I don't know why, a GraphQL request is send with wrong credentials:

DEBUG: POST https://api.github.com/graphql = (code=ERR_NON_2XX_3XX_RESPONSE, statusCode=401 retryCount=0, duration=774) (repository=inversify/monorepo)
 WARN: github.com token 401 unauthorized (repository=inversify/monorepo)
DEBUG: Unexpected GraphQL Error (repository=inversify/monorepo)
       "err": {
         "name": "HTTPError",
         "code": "ERR_NON_2XX_3XX_RESPONSE",
         "timings": {
           "start": 1781108061969,
           "socket": 1781108061970,
           "lookup": 1781108061970,
           "connect": 1781108061970,
           "secureConnect": 1781108061970,
           "upload": 1781108061970,
           "response": 1781108062743,
           "end": 1781108062743,
           "phases": {
             "wait": 1,
             "dns": 1,
             "tcp": 16,
             "tls": 19,
             "request": 0,
             "firstByte": 773,
             "download": 0,
             "total": 774
           }
         },
         "options": {
           "headers": {
             "user-agent": "Renovate/43.220.0 (https://github.com/renovatebot/renovate)",
             "accept": "application/vnd.github.v3+json",
             "authorization": "***********",
             "content-type": "application/json",
             "content-length": "615",
             "accept-encoding": "gzip, deflate, br, zstd"
           },
           "url": "https://api.github.com/graphql",
           "hostType": "github",
           "username": "",
           "password": "",
           "method": "POST",
           "http2": false
         },
         "message": "Request failed with status code 401 (Unauthorized): POST https://api.github.com/graphql",
         "response": {
           "statusCode": 401,
           "statusMessage": "Unauthorized",
           "body": {
             "message": "Requires authentication",
             "documentation_url": "https://docs.github.com/rest",
             "status": "401"
           },
           "headers": {
             "content-type": "application/json; charset=utf-8",
             "x-github-media-type": "github.v3; format=json",
             "access-control-expose-headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
             "access-control-allow-origin": "*",
             "strict-transport-security": "max-age=31536000; includeSubdomains; preload",
             "x-frame-options": "deny",
             "x-content-type-options": "nosniff",
             "x-xss-protection": "0",
             "referrer-policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
             "content-security-policy": "default-src 'none'",
             "vary": "Accept-Encoding, Accept, X-Requested-With",
             "server": "github.com",
             "x-github-request-id": "0410:22B14E:5034328:12DD942C:6A298D5C",
             "date": "Wed, 10 Jun 2026 16:14:22 GMT",
             "connection": "close"
           },
           "httpVersion": "1.1",
           "retryCount": 0
         }
       },
       "query": "\nquery(\n  $owner: String!,\n  $name: String!,\n  $user: String,\n  $count: Int,\n  $cursor: String\n) {\n  repository(owner: $owner, name: $name) {\n    issues(\n      orderBy: { field: UPDATED_AT, direction: DESC },\n      filterBy: { createdBy: $user },\n      first: $count,\n      after: $cursor\n    ) {\n      pageInfo {\n        endCursor\n        hasNextPage\n      }\n      nodes {\n        number\n        state\n        title\n        body\n        updatedAt\n      }\n    }\n  }\n}\n",
       "options": {
         "variables": {
           "owner": "inversify",
           "name": "monorepo",
           "user": "inversify-app[bot]"
         },
         "readOnly": true,
         "count": 100,
         "cursor": null,
         "paginate": true
       }
       HTTPError: Request failed with status code 401 (Unauthorized): POST https://**redacted**@14.6.6/node_modules/got/dist/source/as-promise/index.js:98:42)
           at Object.onceWrapper (node:events:631:26)
           at Request.emit (node:events:521:24)
           at Request.emit (node:domain:489:12)
           at Request._onResponseBase (file:///usr/local/renovate/node_modules/.pnpm/got@14.6.6/node_modules/got/dist/source/core/index.js:779:22)
           at processTicksAndRejections (node:internal/process/task_queues:104:5)
           at Request._onResponse (file:///usr/local/renovate/node_modules/.pnpm/got@14.6.6/node_modules/got/dist/source/core/index.js:829:13)
ERROR: Repository has unknown error (repository=inversify/monorepo)
       "err": {
         "name": "HTTPError",
         "code": "ERR_NON_2XX_3XX_RESPONSE",
         "timings": {
           "start": 1781108061969,
           "socket": 1781108061970,
           "lookup": 1781108061970,
           "connect": 1781108061970,
           "secureConnect": 1781108061970,
           "upload": 1781108061970,
           "response": 1781108062743,
           "end": 1781108062743,
           "phases": {
             "wait": 1,
             "dns": 1,
             "tcp": 16,
             "tls": 19,
             "request": 0,
             "firstByte": 773,
             "download": 0,
             "total": 774
           }
         },
         "options": {
           "headers": {
             "user-agent": "Renovate/43.220.0 (https://github.com/renovatebot/renovate)",
             "accept": "application/vnd.github.v3+json",
             "authorization": "***********",
             "content-type": "application/json",
             "content-length": "615",
             "accept-encoding": "gzip, deflate, br, zstd"
           },
           "url": "https://api.github.com/graphql",
           "hostType": "github",
           "username": "",
           "password": "",
           "method": "POST",
           "http2": false
         },
         "message": "Request failed with status code 401 (Unauthorized): POST https://api.github.com/graphql",
         "response": {
           "statusCode": 401,
           "statusMessage": "Unauthorized",
           "body": {
             "message": "Requires authentication",
             "documentation_url": "https://docs.github.com/rest",
             "status": "401"
           },
           "headers": {
             "content-type": "application/json; charset=utf-8",
             "x-github-media-type": "github.v3; format=json",
             "access-control-expose-headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
             "access-control-allow-origin": "*",
             "strict-transport-security": "max-age=31536000; includeSubdomains; preload",
             "x-frame-options": "deny",
             "x-content-type-options": "nosniff",
             "x-xss-protection": "0",
             "referrer-policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
             "content-security-policy": "default-src 'none'",
             "vary": "Accept-Encoding, Accept, X-Requested-With",
             "server": "github.com",
             "x-github-request-id": "0410:22B14E:5034328:12DD942C:6A298D5C",
             "date": "Wed, 10 Jun 2026 16:14:22 GMT",
             "connection": "close"
           },
           "httpVersion": "1.1",
           "retryCount": 0
         }
       }
       HTTPError: Request failed with status code 401 (Unauthorized): POST https://**redacted**@14.6.6/node_modules/got/dist/source/as-promise/index.js:98:42)
           at Object.onceWrapper (node:events:631:26)
           at Request.emit (node:events:521:24)
           at Request.emit (node:domain:489:12)
           at Request._onResponseBase (file:///usr/local/renovate/node_modules/.pnpm/got@14.6.6/node_modules/got/dist/source/core/index.js:779:22)
           at processTicksAndRejections (node:internal/process/task_queues:104:5)
           at Request._onResponse (file:///usr/local/renovate/node_modules/.pnpm/got@14.6.6/node_modules/got/dist/source/core/index.js:829:13)

The renovate action looks like this:

name: Renovate
on:
  schedule:
    # The "*" (#42, asterisk) character has special semantics in YAML, so this
    # string has to be quoted.
    - cron: "0 0 * * 1"
  workflow_dispatch:
jobs:
  renovate:
    name: Renovate
    environment: CI
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          fetch-depth: 0

      - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
        id: create_token
        with:
          client-id: ${{ vars.GH_APP_ID }}
          private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}

      - name: Self-hosted Renovate
        uses: renovatebot/github-action@693b9ef15eec82123529a37c782242f091365961 # v46.1.14
        env:
          RENOVATE_REPOSITORIES: '[{ repository: "inversify/monorepo", bumpVersion: true }]'
        with:
          configurationFile: config/renovate/renovate-global.json
          token: ${{ steps.create_token.outputs.token }}

Why do I believe this is a bug

  • Removing the options to keep the dashboard solves the issue
  • Using the full renovatebot docker image and global binarySource global options solves the issue.

I checked the token has enough permissions to manage repository issues. Having said that, the server returns 401 and not a 403 status code.

What blows my mind is this config works by simply using the full docker image and global binarySource global options.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Datasource

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions