John Wessel
10/06/2025, 9:48 PMMarvin
10/06/2025, 9:48 PMJohn Wessel
10/06/2025, 9:48 PMJohn Wessel
10/06/2025, 9:49 PMMarvin
10/06/2025, 9:49 PMMarvin
10/06/2025, 9:53 PMfrom prefect import flow
@flow
def my_flow():
return "hello"
flow_obj = type(my_flow).from_source(
source="<https://github.com/<owner>/<repo>>",
entrypoint="path/to/flow_file.py:my_flow",
)
flow_obj.deploy(
name="prod",
work_pool_name="my-pool"
)
CLI example (verified command exists; use from your project root):
prefect deploy ./path/to/flow_file.py:my_flow -n prod
Notes and tips
- Entry point must be of the form path/to/file.py:flow_function_name and must exist on the branch/ref Prefect resolves.
- You do not need (and should not create) GitHub storage blocks in Prefect 3.x. Use from_source(...) and the Cloud connection instead.
- Deprecated in 3.x: Deployment.build_from_flow() and prefect deployment build. Use flow.from_source(...).deploy(...) or prefect deploy.
Common troubleshooting
- Repo not authorized or 404: Ensure the GitHub App is installed on the correct org/account and has access to that repo (All repos or the specific repo). Revisit the app installation in GitHub to adjust repository selection.
- Private repo access fails: Confirm the Prefect Cloud GitHub App is installed and visible as Connected in Prefect Cloud > Connections. Verify the repo URL is exactly <https://github.com/<owner>/<repo>> and your entrypoint path is correct.
- Wrong branch or missing file: Ensure the file path and flow function name in entrypoint match what’s in the default branch (or the branch/tag you’re referencing if applicable).
- GitHub Enterprise: Let me know your host and network constraints. Support can vary depending on whether the host is accessible to Prefect Cloud.
Would you like me to walk you through installing the app for your specific org and repo? If you share the org/account and target repo(s), I can tailor exact steps.
Related docs
- Prefect GitHub integration overview: Prefect + GitHub integration
- Versioning and deploying from source in 3.x: Deploy from source (versioning)
If you need PR checks or other GitHub features, let me know your requirements and I’ll outline what’s supported and how to configure it.Marvin
10/06/2025, 10:05 PMgit_clone pull step during Managed Execution. Even if the app is connected and your repo shows up in uvx prefect-cloud github ls, you still need to explicitly provide credentials to the git_clone step for private repos.
What to do
1) Use HTTPS repo URLs (not SSH)
- git_clone authenticates via HTTPS using a token or a credentials block.
- Example repo format: <https://github.com/org/repo.git>
2) Create a GitHubCredentials block and reference it in your deployment pull step
- Install the GitHub integration:
uv run --with 'prefect[github]' python -c "import sys; print('ok')"
- Create the block (using a token). If you prefer not to use a PAT, reply here and we can discuss GitHub App token options; the most straightforward path is a token-based block:
uv run --with 'prefect[github]' python - << 'PY'
from prefect_github import GitHubCredentials
# Replace with your token that can read the private repo
GitHubCredentials(token="ghp_your_token_here").save("my-gh-creds", overwrite=True)
PY
- Reference the block in prefect.yaml for the git_clone step using Jinja:
pull:
- prefect.deployments.steps.pull.git_clone:
repository: <https://github.com/your-org/your-repo.git>
branch: main
credentials: "{{ prefect.blocks.github-credentials.my-gh-creds }}"
Useful links
- Git clone pull step: git_clone API
- GitHub integration package: prefect-github docs
- Deployment configuration: prefect.yaml guide
Common causes of exit code 128 (auth failures)
- SSH repo URL used instead of HTTPS.
- The GitHub App (or token) lacks Contents: Read permission for that repo or the repo is not included in the app installation scope.
- Repo is private under an org with SSO and your token/app isn’t authorized for that org.
- Branch or commit does not exist (less common for auth errors, but still returns 128 in some git error paths).
- Submodules require their own access and are private (use include_submodules: true and ensure the token/app can access submodules too).
- Org/network IP allowlisting blocks Prefect Cloud egress. If your GitHub org uses IP allowlists, ensure Prefect Cloud IPs are permitted.
How to debug
- Open the flow run logs in Cloud and look for the “pull” step output — git error messages are shown there with sensitive info redacted.
- Temporarily increase verbosity by setting the deployment’s environment to include:
PREFECT_LOGGING_LEVEL=DEBUG
- Reproduce locally with the same credentials and repo:
uv run --with 'prefect[github]' python - << 'PY'
from prefect.deployments.steps.pull import git_clone
from prefect_github import GitHubCredentials
creds = GitHubCredentials.load("my-gh-creds")
print(git_clone(
repository="<https://github.com/your-org/your-repo.git>",
branch="main",
credentials=creds
))
PY
A couple of clarifying questions so I can get you to green quickly:
- What’s the exact repo URL in your deployment (HTTPS vs SSH)?
- Are you defining your git_clone step in prefect.yaml? If so, can you share that snippet (redact secrets)?
- Does the GitHub App have Contents: Read permission and is it installed on the specific repo?
- Is the repo under an org that enforces SSO or IP allowlists?
If you’d prefer to rely on the GitHub App integration instead of a PAT-backed block, I can help explore options for issuing installation tokens at pull time — but that still requires wiring credentials into the git_clone step today; it’s not auto-injected.John Wessel
10/07/2025, 12:05 AMMarvin
10/07/2025, 12:05 AMMarvin
10/07/2025, 12:06 AM.git, move orgs, rename the repo, or point to a different fork) Prefect refuses to reuse the cached directory and raises “does not match the configured repository.”
How to fix it quickly
Pick one of these:
1) Standardize the repository URL
- Make sure your deployment’s repository exactly matches what was used previously, including protocol and .git suffix. Prefer consistent HTTPS URLs like:
<https://github.com/<owner>/<repo>.git>
Then re-run.
2) Pin a commit SHA (forces a new cache path)
- Updating to a specific commit often avoids collisions:
pull:
- prefect.deployments.steps.pull.git_clone:
repository: <https://github.com/<owner>/<repo>.git>
commit_sha: "<full_commit_sha>"
credentials: "{{ prefect.blocks.github-credentials.my-gh-creds }}"
3) Clear the stale cached directory before cloning
- Add a shell step to remove the existing directory, then clone:
pull:
- prefect.deployments.steps.utility.run_shell_script:
script: |
# Replace with the exact directory Prefect is reporting
rm -rf /opt/prefect/<repo>-<branch> || true
- prefect.deployments.steps.pull.git_clone:
repository: <https://github.com/<owner>/<repo>.git>
branch: main
credentials: "{{ prefect.blocks.github-credentials.my-gh-creds }}"
Be precise with the path to avoid deleting something unintended.
Helpful checks and diagnostics
- Print the “origin” of the pre-existing repo to see what it was pointing to:
pull:
- prefect.deployments.steps.utility.run_shell_script:
script: |
if [ -d /opt/prefect/<repo>-<branch>/.git ]; then
git -C /opt/prefect/<repo>-<branch> remote -v || true
fi
- prefect.deployments.steps.pull.git_clone:
repository: <https://github.com/<owner>/<repo>.git>
branch: main
credentials: "{{ prefect.blocks.github-credentials.my-gh-creds }}"
Reminders for private repos
- Use HTTPS URLs, not SSH.
- Provide credentials explicitly to git_clone. Example with a GitHubCredentials block:
pull:
- prefect.deployments.steps.pull.git_clone:
repository: <https://github.com/<owner>/<repo>.git>
branch: main
credentials: "{{ prefect.blocks.github-credentials.my-gh-creds }}"
References
- git_clone step: git_clone API
If you can share:
- The exact repository currently configured
- Whether it changed recently (SSH → HTTPS, org move, repo rename)
- The path shown in the error (/opt/prefect/...)
…I can suggest the safest exact rm -rf path or the best option among the three above for your setup.