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

  1. Read the embedded stderr in the error message - it names the exact git failure to fix
  2. Fetch inside the submodule so the target commit exists: git -C <sm_dir> fetch --all-tags, then retry the discard
  3. Repair the submodule checkout manually (git -C <sm_dir> status) and resolve lock/permission issues, then retry
  4. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/e8e382c049ac1b8a. Report an issue: GitHub.