gitbutlerapp/gitbutler · error
When using GitButler's API to summarize code, you must be lo
Error message
When using GitButler's API to summarize code, you must be logged in
What it means
Raised when discarding submodule changes: the code shells out to 'git reset --hard <id> && git clean -fxd' inside the submodule directory and the subprocess exits non-zero. The message embeds the submodule path, the target commit id, and git's stderr, so the underlying git failure is the real diagnostic.
Source
Thrown at apps/desktop/src/lib/ai/service.ts:314
async validateGitButlerAPIConfiguration(): Promise<boolean> {
if (!(await this.usingGitButlerAPI())) {
return false;
}
return !!get(this.tokenMemoryService.token);
}
// This optionally returns a summarizer. There are a few conditions for how this may occur
// Firstly, if the user has opted to use the GB API and isn't logged in, it will return undefined
// Secondly, if the user has opted to bring their own key but hasn't provided one, it will return undefined
async buildClient(): Promise<AIClient | undefined> {
const modelKind = await this.getModelKind();
if (await this.usingGitButlerAPI()) {
// TODO(CTO): Once @estib has landed the new auth, it would be good to
// about a good way of checking whether the user is authenticated.
if (!get(this.tokenMemoryService.token)) {
throw new Error("When using GitButler's API to summarize code, you must be logged in");
}
return new ButlerAIClient(this.cloud, modelKind);
}
if (modelKind === ModelKind.Ollama) {
const ollamaEndpoint = await this.getOllamaEndpoint();
const ollamaModelName = await this.getOllamaModelName();
return new OllamaClient(ollamaEndpoint, ollamaModelName);
}
if (modelKind === ModelKind.LMStudio) {
const lmStudioEndpoint = await this.getLMStudioEndpoint();
const lmStudioModelName = await this.getLMStudioModelName();
if (!lmStudioEndpoint) {
throw new Error("When using LM Studio, you must provide a valid endpoint");
}View on GitHub (pinned to caf1f223d3)
Solutions
- Read the embedded stderr in the error message - it names the exact git failure to fix
- Fetch inside the submodule so the target commit exists: git -C <sm_dir> fetch --all-tags, then retry the discard
- Repair the submodule checkout manually (git -C <sm_dir> status) and resolve lock/permission issues, then retry
- If the submodule directory was removed externally, reinitialize it (git submodule update --init) before discarding
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the submodule can reach the target commit before discarding
let sm = std::path::Path::new(sm_dir);
if sm.join(".git").exists() {
let out = std::process::Command::new("git")
.args(["-C", sm_dir, "cat-file", "-e", &format!("{id}^{{commit}}", id = state.id)])
.output()?;
anyhow::ensure!(out.status.success(), "submodule cannot resolve {} - fetch it first", state.id);
} Try / catch
match discard_workspace_changes(repo, specs, ctx) {
Err(err) if err.to_string().contains("Could not reset submodule") => {
// log err (contains git stderr), fetch in the submodule, retry once
}
other => other.map(|_| ()),
} Prevention
- Keep submodules fetched (git submodule update --remote or periodic fetch) before discarding their changes
- Ensure 'git' is on PATH for processes using gix shell-outs
- Avoid running other git commands inside submodule directories mid-operation
When it happens
Trigger: discard_workspace_changes on a path whose previous state is a submodule (gitlink) whose worktree content no longer matches state.id. git reset then fails because the commit is missing from the submodule, the submodule checkout is on an unrelated history, files are read-only or locked, the submodule working directory was deleted, or 'git' is not resolvable via the shell.
Common situations: Submodule commit not fetched (shallow clone, missing remote fetch), submodule initialized at a different origin, read-only files after a CI copy or Windows permission issues, antivirus/index.lock contention, or a concurrently running git process inside the submodule.
Related errors
- Invalid token format
- Failed to communicate with LM Studio server: ${error instanc
- Invalid response: ${JSON.stringify(result)}
- When using LM Studio, you must provide a valid endpoint
- When using OpenAI in a bring your own key configuration, you
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/e8e382c049ac1b8a.
Report an issue: GitHub.