crewAIInc/crewAI · warning · SystemExit
Failed to publish tool. Local changes need to be resolved be
Error message
Failed to publish tool. Local changes need to be resolved before publishing. Please do the following: * Commit your changes. * Push to sync with the remote. * Pull the latest changes from the remote. Once your repository is up-to-date, retry publishing the tool.
What it means
Raised (SystemExit with no code, i.e. exit 0) by ToolCommand.publish() in crewai_cli/tools/main.py when git.Repository().is_synced() returns False and --force was not passed. Publishing packages the current project as a tool; the CLI requires a clean, committed, pushed and up-to-date git state so the published artifact is traceable to a commit.
Source
Thrown at lib/cli/src/crewai_cli/tools/main.py:115
self.login()
subprocess.run(["git", "init"], check=True) # noqa: S607
console.print(
f"[green]Created custom tool [bold]{folder_name}[/bold]. Run [bold]cd {project_root}[/bold] to start working.[/green]"
)
finally:
os.chdir(old_directory)
def publish(self, is_public: bool, force: bool = False) -> None:
if not git.Repository().is_synced() and not force:
console.print(
"[bold red]Failed to publish tool.[/bold red]\n"
"Local changes need to be resolved before publishing. Please do the following:\n"
"* [bold]Commit[/bold] your changes.\n"
"* [bold]Push[/bold] to sync with the remote.\n"
"* [bold]Pull[/bold] the latest changes from the remote.\n"
"\nOnce your repository is up-to-date, retry publishing the tool."
)
raise SystemExit()
project_name = get_project_name(require=True)
assert isinstance(project_name, str) # noqa: S101
project_version = get_project_version(require=True)
assert isinstance(project_version, str) # noqa: S101
project_description = get_project_description(require=False)
encoded_tarball = None
console.print("[bold blue]Discovering tools from your project...[/bold blue]")
project_utils = _require_project_utils()
available_exports = project_utils.extract_available_exports()
if available_exports:
console.print(
f"[green]Found these tools to publish: {', '.join([e['name'] for e in available_exports])}[/green]"
)View on GitHub (pinned to 754d7323be)
Solutions
- Commit all local changes: `git add -A && git commit -m "..."`.
- Push and synchronize: `git push` then `git pull` so is_synced() passes.
- If the repo state is intentionally dirty (e.g. CI), pass --force: `crewai tool publish --force`.
- Ensure a remote origin is configured (`git remote -v`) — no remote means never synced.
Example fix
# before crewai tool publish --public # uncommitted changes -> SystemExit # after git add -A && git commit -m "chore: publish tool v0.1.1" && git push git pull grewai tool publish --public # typo guard: crewai tool publish --public
Defensive patterns
Strategy: validation
Validate before calling
import subprocess
def git_is_synced() -> bool:
def clean(cmd):
return subprocess.run(cmd, capture_output=True, text=True).stdout.strip() == ""
return (
clean(["git", "status", "--porcelain"])
and clean(["git", "log", "@{u}..", "--oneline"])
and clean(["git", "log", "..@{u}", "--oneline"])
) Prevention
- Commit and push before every `crewai tool publish`
- Wire publish jobs after a sync step in CI so the checkout is clean and up to date
- Reserve --force for pipelines where dirty state is guaranteed and understood
When it happens
Trigger: Running `crewai tool publish` with uncommitted changes, commits not pushed to the remote, local branch behind the remote (unpulled changes), or no remote configured — and without the --force flag.
Common situations: Developer edits pyproject.toml or tool code and publishes without committing; CI publish job running on a checkout that never pushes; detached HEAD or freshly cloned repo that is ahead of origin.
Related errors
- {self.path} is not a Git repository.
- Unable to validate git state: {exc} Fix the issue or pass --
- Failed to publish skill. Local changes need to be resolved b
- SKILL.md frontmatter must include a 'name' field.
- Invalid JSON payload provided as argument
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/845176866f3819b6.
Report an issue: GitHub.