Git Submodule Not Initialized Error — Fix (2026)
The Error
fatal: No url found for submodule path 'lib/shared-utils' in .gitmodules
Error: Claude Code cannot read files in 'lib/shared-utils/' — directory is empty
Submodule 'lib/shared-utils' is registered but not initialized
This appears when Claude Code tries to read or edit files inside a git submodule directory that has not been cloned yet, finding an empty directory instead of source files.
The Fix
git submodule update --init --recursive
- Initialize and clone all registered submodules.
- Verify the submodule directory now contains files:
ls lib/shared-utils/. - Resume your Claude Code session — it can now read and edit submodule files.
Why This Happens
Git submodules are separate repositories embedded within a parent repo. After a fresh git clone, submodule directories exist but are empty until explicitly initialized. Claude Code does not automatically run git submodule update and treats the empty directory as though the files do not exist. This commonly occurs in CI/CD environments, fresh clones, or when a teammate adds a new submodule.
If That Doesn’t Work
If the submodule URL has changed or is inaccessible:
git submodule sync --recursive
git submodule update --init --recursive
If the submodule is pinned to a detached commit that no longer exists:
cd lib/shared-utils
git fetch origin
git checkout main
cd ../..
Remove and re-add a corrupted submodule:
git submodule deinit lib/shared-utils
git rm lib/shared-utils
rm -rf .git/modules/lib/shared-utils
git submodule add <url> lib/shared-utils
Prevention
# CLAUDE.md rule
After cloning this repo, always run 'git submodule update --init --recursive'. Submodule directories: lib/shared-utils, vendor/third-party. These must be initialized before editing.
Related Error Messages
This fix also applies if you see these related error messages:
fatal: not a git repositoryerror: failed to push some refsfatal: refusing to merge unrelated historiesError: ENOENT: no such file or directoryCannot resolve path outside workspace
Frequently Asked Questions
Why does Claude Code require git?
Claude Code uses git for several core operations: tracking file changes, creating commits, reading blame information, searching history with git log, and managing branches. Without git, these operations fail and Claude Code falls back to less efficient alternatives.
Can Claude Code work in a non-git directory?
Yes, but with reduced functionality. File search and editing work normally, but version control operations (commit, diff, blame) are unavailable. Claude Code displays a warning when opened in a directory without git initialization.
How do I prevent Claude Code from making unwanted git operations?
Add rules to your CLAUDE.md: Do not create commits automatically. Do not run git push. Always ask before any git operation that modifies history. Claude Code respects these constraints and asks for confirmation before proceeding.
Why does Claude Code reject paths outside the workspace?
Claude Code sandboxes file operations to the current workspace directory for security. Writing to paths outside the project root (like /etc/ or ~/) is blocked by default. This prevents accidental modification of system files or other projects.
Related Guides
Configure permissions → Build your settings with our Permission Configurator.
Try it: Paste your error into our Error Diagnostic for an instant fix.
- Terminal Emulator Rendering Artifacts — Fix (2026)
- How to Use Thirdweb SDK Workflow (2026)
- Python Virtualenv Not Activated — Fix (2026)
- Claude Code Offline Mode Setup (2026)
Git Operations in Claude Code: Safety Checklist
Claude Code can execute git commands, which makes safety guardrails important:
Before any destructive operation: Always check git status and git stash list to confirm there are no uncommitted changes that could be lost.
Branch management: Claude Code should create feature branches for non-trivial changes rather than committing directly to main. Use the pattern git checkout -b claude/feature-name to clearly identify AI-generated branches.
Commit message conventions: Configure your preferred commit format in CLAUDE.md. Claude Code follows the format you specify. Common formats: Conventional Commits (feat: add user search), Angular style, or simple descriptive messages.
Common Git Mistakes Claude Code Makes
-
Amending the wrong commit. If a pre-commit hook fails, Claude Code sometimes uses
--amendon the next attempt, which modifies the previous (successful) commit instead of creating a new one. Configure CLAUDE.md with: “Never use git commit –amend. Always create new commits.” -
Force pushing to shared branches. Claude Code may suggest
git push --forceto resolve push rejections. AddBash(git push --force*)to your deny list in settings.json. -
Committing generated files. Without guidance, Claude Code may commit
dist/,node_modules/, or.envfiles. Ensure your.gitignoreis complete and add a pre-commit hook that checks for these.