{"record":{"id":"e5f23ad124cd34cb","repo":"crewAIInc/crewAI","slug":"failed-to-publish-skill-local-changes-need-to-be","errorCode":null,"errorMessage":"Failed to publish skill.\nLocal changes need to be resolved before publishing. Please do the following:\n* Commit your changes.\n* Push to sync with the remote.\n* Pull the latest changes from the remote.\n\nOnce your repository is up-to-date, retry publishing the skill (or pass --force to skip this check).","messagePattern":"Failed to publish skill\\.\nLocal changes need to be resolved before publishing\\. Please do the following:\n\\* Commit your changes\\.\n\\* Push to sync with the remote\\.\n\\* Pull the latest changes from the remote\\.\n\nOnce your repository is up-to-date, retry publishing the skill \\(or pass --force to skip this check\\)\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/skills/main.py","lineNumber":229,"sourceCode":"                    # against the actual remote, not stale local state.\n                    repository.fetch()\n                except ValueError as exc:\n                    console.print(\n                        f\"[red]Unable to validate git state: {exc}\\n\"\n                        \"Fix the issue or pass --force to skip this check.[/red]\"\n                    )\n                    raise SystemExit(1) from exc\n            if repository is not None and not repository.is_synced():\n                console.print(\n                    \"[bold red]Failed to publish skill.[/bold red]\\n\"\n                    \"Local changes need to be resolved before publishing. Please do the following:\\n\"\n                    \"* [bold]Commit[/bold] your changes.\\n\"\n                    \"* [bold]Push[/bold] to sync with the remote.\\n\"\n                    \"* [bold]Pull[/bold] the latest changes from the remote.\\n\"\n                    \"\\nOnce your repository is up-to-date, retry publishing the skill \"\n                    \"(or pass --force to skip this check).\"\n                )\n                raise SystemExit(1)\n\n        try:\n            frontmatter = self._parse_frontmatter(skill_md.read_text(encoding=\"utf-8\"))\n        except ValueError as exc:\n            console.print(f\"[red]Failed to parse SKILL.md frontmatter: {exc}[/red]\")\n            raise SystemExit(1) from exc\n\n        name = frontmatter.get(\"name\")\n        raw_metadata = frontmatter.get(\"metadata\")\n        version = (\n            raw_metadata.get(\"version\") if isinstance(raw_metadata, dict) else None\n        )\n        description = frontmatter.get(\"description\")\n\n        if not name:\n            console.print(\n                \"[red]SKILL.md frontmatter must include a 'name' field.[/red]\"\n            )","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/skills/main.py#L211-L247","documentation":"`repository.is_synced()` returned False after a successful fetch, meaning local branch state diverges from the remote: uncommitted changes, unpushed commits, or the remote is ahead. The CLI refuses to publish from a dirty repo so that published skill versions always map to a traceable git state, unless `--force` is passed.","triggerScenarios":"Running `crewai skill publish` with modified/untracked files, local commits not pushed, or remote commits not pulled. The exact condition is `repository is not None and not repository.is_synced()` inside the non-`--force` branch.","commonSituations":"Editing SKILL.md (e.g. bumping the version) and immediately publishing without committing; working on a branch never pushed; collaborating where a teammate pushed after your last pull.","solutions":["Commit all changes, push, and pull: `git add -A && git commit -m '...' && git push && git pull --rebase`, then re-run `crewai skill publish`.","If git cleanliness is not required (e.g. local-only experiment), use `crewai skill publish --force`."],"exampleFix":"# before\nvim SKILL.md   # bump version\ncrewai skill publish   # Failed to publish skill. Local changes need to be resolved...\n\n# after\ngit add SKILL.md && git commit -m \"bump skill version\" && git push\ncrewai skill publish","handlingStrategy":"validation","validationCode":"import subprocess\n\ndef repo_is_clean_and_synced() -> bool:\n    def ok(*args):\n        return subprocess.run([\"git\", *args], capture_output=True).returncode == 0\n    return ok(\"diff\", \"--quiet\") and ok(\"diff\", \"--cached\", \"--quiet\") and ok(\"diff\", \"--quiet\", \"@{u}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Commit and push SKILL.md version bumps before every publish.","Pull/rebase before publishing in shared repos.","Reserve `--force` for local-only experiments; treat the dirty-repo refusal as a safety net, not an obstacle."],"tags":["cli","git","publish","skill","workflow"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}