# GitHub Actions: secret is empty on pull_request from a fork or Dependabot (Secrets are not passed to workflows triggered by a fork)

**Code:** `secrets not available in pull requests from forks` · **Category:** CI/CD · **Seen on:** GitHub Actions

Secrets are intentionally withheld from workflows that run for pull requests from forks and, by default, for Dependabot PRs — so `${{ secrets.X }}` is an empty string.

## Meaning

This protects your secrets from untrusted code. Steps that need a secret then fail with "Input required and not supplied" or an authentication error. Run secret-free checks on `pull_request`, and use `pull_request_target` or `workflow_run` only with great care (never check out and run untrusted PR code with secrets).

## Common causes

- PR opened from a fork (secrets and write token are not provided)
- Dependabot-triggered run using Actions secrets instead of Dependabot secrets
- Secret defined at the wrong level (environment vs repository)
- Secret name misspelled
- Environment protection rules not met

## Quick fix

1. Keep untrusted PR jobs secret-free (build and test only)
2. Add the secrets under Settings → Secrets → Dependabot for Dependabot PRs
3. Use `workflow_run` / `pull_request_target` with a hardened design if you must comment or publish

## Detailed fix by platform

### GitHub Actions

1. Fork-safe pattern: build on `pull_request`, upload an artifact, then a separate `workflow_run` job (with secrets) reads the artifact data but never executes it

## Code examples

### Skip secret steps for forks

```yaml
- name: Deploy preview
  if: github.event.pull_request.head.repo.full_name == github.repository   # not from a fork
  env:
    TOKEN: ${{ secrets.PREVIEW_TOKEN }}
  run: ./preview.sh
```

## How to diagnose

1. **Origin** — Is the PR from a fork or Dependabot?
2. **Level** — Where is the secret defined?
3. **Needs** — Does the step really require a secret?

---
Source: [WhatIsMyError](https://whatismyerror.com/errors/cicd/gha-secrets-empty-pull-request-fork)
