GH013: Push cannot contain secrets

GitHub found an API key or other secret in the commits you tried to push and blocked the whole push so the secret wouldn’t land in the repository.

Terminal
remote: error: GH013: Repository rule violations found for refs/heads/main. remote: remote: - GITHUB PUSH PROTECTION remote: ————————————————————————————————————————— remote: Resolve the following violations before pushing again remote: remote: - Push cannot contain secrets remote: remote: remote: (?) Learn how to resolve a blocked push remote: https://docs.github.com/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-from-the-command-line#resolving-a-blocked-push remote: remote: remote: —— OpenAI API Key ———————————————————————————————————— remote: locations: remote: - commit: 3f9c2a1d8e7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a remote: path: .env:2 remote: remote: (?) To push, remove secret from commit(s) or follow this URL to allow the secret. remote: https://github.com/acme/my-app/security/secret-scanning/unblock-secret/2pXk9vQmT4bL7nRw1sYc8ZfHj3e remote: To https://github.com/acme/my-app.git ! [remote rejected] main -> main (push declined due to repository rule violations) error: failed to push some refs to 'https://github.com/acme/my-app.git'

Also appears as

  • remote: error GH009: Secrets detected! This push failed.

Prompt to fix it

git push was blocked by GitHub push protection: "GH013: Repository rule violations found" and "Push cannot contain secrets". Find every secret listed in the error and move it into environment variables, add .env files to .gitignore, and stop tracking them with git rm --cached. Then rewrite only my unpushed commits so none of them contains the secret, and push again. Don’t use the allow-secret link, and don’t force push over commits that are already on GitHub. Tell me which keys I need to rotate.

Paste into Layerwise or any AI coding tool.

What it means

GitHub push protection scans every push for known secret formats: API keys from OpenAI, Stripe, AWS, Supabase, and many more. When it finds one, it rejects the entire push and lists each secret by type, commit, and file line. It checks every commit in the push, so deleting the key in a new commit doesn’t help while an older commit still contains it.

Most of the time the file is .env. AI tools often create it with real keys, and if .gitignore doesn’t list it, git add . commits it. Sometimes the key sits in source code instead, pasted into a config file or a fetch call.

The block kept the key off GitHub, but rotate it anyway: the commit may also exist in other clones, backups, or remotes, and a new key takes a minute to make. GitHub’s link to allow the secret puts it into the repository’s history, where anyone with access can read it, so use it only for test or fake values.

Common causes

  • .env or .env.local isn’t listed in .gitignore, so git add . committed real keys.
  • A key was pasted straight into source code, such as an OpenAI or Stripe secret key in a config file.
  • The key was removed in a later commit, but an earlier commit in the same push still has it.
  • A sample file like .env.example or a test fixture contains a real key.

How to fix it

  1. Read the locations list. It names each commit and file:line that holds a secret.
  2. Rotate the key: create a new one in the provider’s dashboard, update it wherever the app runs, and revoke the old one.
  3. Move secrets into environment variables. Add .env* to .gitignore, with !.env.example if you share a template, then run git rm --cached .env.
  4. If only your latest commit has the secret, remove it and run git commit --amend --no-edit. If older unpushed commits have it, run git reset --soft origin/main to undo those commits while keeping every change staged, then commit again.
  5. Push again. Because none of the new commits contain the secret, a normal git push works.

Example fix

# Keep .env files out of git from now on.
printf '.env*\n!.env.example\n' >> .gitignore
git rm --cached .env

# Undo the unpushed commits but keep every change staged.
git reset --soft origin/main
git add .gitignore
git commit -m "Add app without secrets"
git push
All errors
OpenAIError: It looks like you're running in a browser-like environment. This is disabled by default, as it risks exposing your secret API credentials to attackers. If you understand the risks and have appropriate mitigations in place, you can set the `dangerouslyAllowBrowser` option to `true`, e.g., new OpenAI({ apiKey, dangerouslyAllowBrowser: true }); https://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety

It looks like you're running in a browser-like environment

The AI SDK refused to run in the browser, because your secret API key would be visible to anyone who opens the page.

To https://github.com/acme/my-app.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'https://github.com/acme/my-app.git' hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Failed to push some refs

GitHub has commits your copy doesn’t, so git refused to overwrite them until you bring those changes in.

AuthenticationError: 401 Incorrect API key provided: sk-proj-************************************************bb0A. You can find your API key at https://platform.openai.com/account/api-keys.

Incorrect API key provided

The AI API rejected the key your code sent: it has a typo, was revoked, or isn’t the key you think the app is using.

fatal: not a git repository (or any of the parent directories): .git

fatal: not a git repository

Git searched this folder and every folder above it and found no repository, so the command has nothing to work on.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.