Skip to content

/tree branch summarization throws "No API key found" for ambient-credential providers (Bedrock, Vertex) #6324

Description

@yuval-shimoni-cyera

Bug: /tree branch summarization throws "No API key found" for ambient-credential providers (Bedrock, Vertex)

pi version: 0.80.3
Provider: amazon-bedrock (also affects any provider whose auth is ambient / has no apiKey, e.g. Google Vertex AI)

Summary

Using /tree, selecting a message, and choosing to summarize the abandoned
branch fails with:

Error: No API key found for amazon-bedrock.

…even though Bedrock is fully configured and working for normal turns and for
/compact. The branch-summarization path uses the strict auth resolver instead
of the lenient one that compaction uses.

Root cause

In packages/coding-agent/src/core/agent-session.js (compiled) /
agent-session.ts, branch summarization resolves auth via
_getRequiredRequestAuth:

// branch summarization
const model = this.model;
const { apiKey, headers, env } = await this._getRequiredRequestAuth(model);
const result = await generateBranchSummary(entriesToSummarize, {
    model, apiKey, headers, env,
    streamFn: this.agent.streamFn,
    ...
});

_getRequiredRequestAuth calls getApiKeyAndHeaders(model) (which resolves with
includeFallback: false) and then throws when there is no apiKey:

if (result.apiKey) return { ... };
const isOAuth = this._modelRegistry.isUsingOAuth(model);
if (isOAuth) throw ...;
throw new Error(formatNoApiKeyFoundMessage(model.provider)); // <-- thrown for Bedrock

Bedrock auth is ambient — the AWS SDK signs requests from the credential chain
(AWS_PROFILE, IAM keys, bearer token, ECS/IRSA), so apiKey is legitimately
undefined. It is not OAuth. So the strict resolver always throws.

Compaction does not have this problem because it uses the lenient
_getCompactionRequestAuth, which tolerates a missing apiKey:

async _getCompactionRequestAuth(model) {
    if (this.agent.streamFn === streamSimple) {
        return this._getRequiredRequestAuth(model);
    }
    const result = await this._modelRegistry.getApiKeyAndHeaders(model);
    return result.ok ? { apiKey: result.apiKey, headers: result.headers, env: result.env } : {};
}

Note that branch summarization already passes streamFn: this.agent.streamFn
(the wrapper that resolves AWS credentials itself), so once the premature throw
is avoided, the summary generates correctly — identical to how compaction works.

Fix

Have branch summarization use the lenient resolver, matching compaction:

- const { apiKey, headers, env } = await this._getRequiredRequestAuth(model);
+ const { apiKey, headers, env } = await this._getCompactionRequestAuth(model);

Reproduction

  1. Configure Bedrock via AWS_PROFILE (no apiKey in auth.json).
  2. Start pi with --provider amazon-bedrock --model us.anthropic.claude-....
  3. Have a branching conversation.
  4. /tree → navigate to a different branch → choose to summarize the abandoned branch.
  5. Observe No API key found for amazon-bedrock.

Normal turns and /compact work fine in the same session, which confirms the
credentials are valid and the issue is isolated to the branch-summary auth path.

Metadata

Metadata

Assignees

Labels

inprogressIssue is being worked on

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions