Skip to content

Use the chat organization for Claude Web - #1126

Open
sebastianelsner wants to merge 3 commits into
ChatGPTBox-dev:masterfrom
sebastianelsner:fix/claude-web-chat-organization
Open

sebastianelsner wants to merge 3 commits into
ChatGPTBox-dev:masterfrom
sebastianelsner:fix/claude-web-chat-organization

Conversation

@sebastianelsner

@sebastianelsner sebastianelsner commented Oct 25, 2026 •

Copy link
Copy Markdown

Summary

Claude.ai (Web) fails with s.map is not a function for accounts linked to the Anthropic Console. /api/organizations lists the API-only organization first (capabilities ["api", "customer_terms:standard"]), and Claude.init() always took organizations[0]. claude.ai answers chat_conversations for that organization with a permission_error object instead of a list:

 Claude.init()
   getOrganizations()
-  organizationId = organizations[0].uuid
+  organizationId = first organization whose capabilities include "chat"
+                   ?? organizations[0]
   getConversations()
-    json.map(...)   // json = { type: "error", error: { type: "permission_error" } } → TypeError
+    if json is not an array → throw Error(json.error.message)
+    json.map(...)

The client's fetch-sse import also gets its .mjs extension so the module loads under the Node test runner. Webpack resolves both forms the same way.

Evidence

  • Before: the new tests run against the old init():

    ✖ Claude init prefers the organization with chat capability
      Error: unexpected request /api/organizations/api-org/chat_conversations
    ✖ Claude init reports the claude.ai error when conversations are denied
      actual: TypeError: json.map is not a function
    

    In the extension, every Claude.ai (Web) question ends with the error s.map is not a function.

    After:

    ✔ Claude init prefers the organization with chat capability
    ✔ Claude init falls back to the first organization without chat capability
    ✔ Claude init reports the claude.ai error when conversations are denied
    

    Claude.ai (Web) answers normally again in Firefox for the affected account.

Validation: npm test (1110 pass), npm run lint, npm run pretty:check and npm run build are clean. Manually tested in Firefox with an affected account, using a build that also carried #996; the Claude client code is identical to this PR. Not manually tested in Chromium.

Merge Danger

Door: two-way

Blast Radius: Claude Web only

Accounts with a single organization, or whose first organization already has chat, keep the organization they used before. If claude.ai stops reporting chat in capabilities, the client falls back to the old organizations[0] behavior.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Claude now selects an organization with chat access when available, and falls back to the first organization when none has chat access.
    • Conversation-loading failures now show the service’s error message when available. If the response is not a list of conversations, the response details are shown instead.
    • Initialization now reports permission errors returned while loading conversations.

Accounts linked to the Anthropic Console list an API-only organization
first. claude.ai answers chat_conversations for it with a
permission_error object, which crashed init() with "s.map is not a
function". Prefer the organization with the chat capability and turn a
non-array conversations response into a readable error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T15:05:37.078505Z a031c94 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d6538b10-a3a8-423f-a801-b860e40f5a1a
Commits

Reviewing files that changed from the base of the PR and between 23dd3f8 and 462a0e8.

Files selected for processing: 2
  • src/services/clients/claude/index.mjs
  • tests/unit/services/clients/claude.test.mjs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The Claude client now selects an organization with chat capability when available and reports errors when conversation responses are not arrays. Unit tests cover organization selection, fallback selection, and invalid conversation responses.

Changes: Claude client initialization

Layer / File(s) Summary
Organization selection
src/services/clients/claude/index.mjs, tests/unit/services/clients/claude.test.mjs
The client selects the first organization with chat capability, or the first organization when none match. The fetch-sse.mjs import now includes its file extension. Tests cover both selection cases.
Conversation response errors
src/services/clients/claude/index.mjs, tests/unit/services/clients/claude.test.mjs
getConversations() throws the API-provided error message when the response is not an array, or the serialized response otherwise. Tests cover a permission error and a non-list response.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: josstorer

Merge Risk: Minimal · up to 462a0

No actionable merge-blocking risk is established for this change.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within survi… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: selecting the chat-capable organization for Claude Web.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 2 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Select the chat-capable organization for Claude Web

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Prefer a chat-capable organization so Console-linked accounts can load Claude Web conversations.
• Report conversation API errors instead of failing while mapping an error response.
• Add initialization tests and make the SSE import resolvable by Node’s test runner.
Diagram

graph TD
  A["Claude init"] --> B{"Chat capable?"} -->|Yes| C["Chat org"] --> E["Fetch conversations"] --> F{"Array response?"} -->|Yes| G["Conversation objects"]
  B -->|No| D["First org"] --> E
  F -->|No| H["API error"]
Loading
High-Level Assessment

Prefer the advertised chat capability with the existing first-organization fallback: it fixes affected accounts without additional API requests or changing behavior when no chat capability is reported. Probing organizations through conversation requests would add network calls and error-handling complexity.

Files changed (2) +65 / -2

Bug fix (1) +9 / -2
index.mjsChoose a chat-capable organization and validate conversations +9/-2

Choose a chat-capable organization and validate conversations

• Initialization now prefers an organization advertising chat capability and otherwise retains the first organization. Conversation loading throws the API's message, or a fallback error, for non-array responses. The SSE import gains an explicit extension for Node module resolution.

src/services/clients/claude/index.mjs

Tests (1) +56 / -0
claude.test.mjsCover Claude Web initialization and error responses +56/-0

Cover Claude Web initialization and error responses

• Adds mocked-fetch tests for chat-organization preference, first-organization fallback, and propagation of a denied-conversations message.

tests/unit/services/clients/claude.test.mjs

@qodo-code-review

qodo-code-review Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Non-English users see an English fallback ✗ Dismissed
Description
getConversations() throws the hardcoded failed to load conversations message without an English
localization key. When Claude returns a non-array response without an error message, the failure
reaches the conversation UI and remains untranslated for non-English locales.
Code

src/services/clients/claude/index.mjs[R355-356]

+    if (!Array.isArray(json)) {
+      throw new Error(json?.error?.message || 'failed to load conversations')
Evidence
The changed code introduces the user-visible fallback string when conversations cannot be loaded.
Claude.init() awaits this method, the error propagates through the Claude Web API path, and the
conversation UI displays the resulting error through the localization layer; however, no matching
locale key exists, violating the requirement to add new English localization keys before other
locales.

Rule 2262059: Add new English localization keys before other locales
src/services/clients/claude/index.mjs[355-356]
src/services/clients/claude/index.mjs[193-200]
src/components/ConversationCard/index.jsx[245-285]
src/utils/error-text.mjs[36-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fallback error message in `getConversations()` is hardcoded and has no corresponding localization key, so it can be shown untranslated in the conversation UI.

## Fix Focus Areas
- src/services/clients/claude/index.mjs[355-356]
- src/_locales/en/main.json[1-1]
- src/_locales/resources.mjs[1-38]

## Recommended Fix
Add an English localization key for the fallback message and add the corresponding key to supported locale files according to the project convention. Pass the localized message or localization key through the existing error-display path instead of hardcoding the user-facing English text in the client.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 6 rules
Review mode: Auto: 🚀 Fast: Localized test-only changes with contained, low-risk coverage.

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 462a0e8

Results up to commit a031c94 🚀 Fast


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Non-English users see an English fallback ✗ Dismissed
Description
getConversations() throws the hardcoded failed to load conversations message without an English
localization key. When Claude returns a non-array response without an error message, the failure
reaches the conversation UI and remains untranslated for non-English locales.
Code

src/services/clients/claude/index.mjs[R355-356]

+    if (!Array.isArray(json)) {
+      throw new Error(json?.error?.message || 'failed to load conversations')
Evidence
The changed code introduces the user-visible fallback string when conversations cannot be loaded.
Claude.init() awaits this method, the error propagates through the Claude Web API path, and the
conversation UI displays the resulting error through the localization layer; however, no matching
locale key exists, violating the requirement to add new English localization keys before other
locales.

Rule 2262059: Add new English localization keys before other locales
src/services/clients/claude/index.mjs[355-356]
src/services/clients/claude/index.mjs[193-200]
src/components/ConversationCard/index.jsx[245-285]
src/utils/error-text.mjs[36-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fallback error message in `getConversations()` is hardcoded and has no corresponding localization key, so it can be shown untranslated in the conversation UI.

## Fix Focus Areas
- src/services/clients/claude/index.mjs[355-356]
- src/_locales/en/main.json[1-1]
- src/_locales/resources.mjs[1-38]

## Recommended Fix
Add an English localization key for the fallback message and add the corresponding key to supported locale files according to the project convention. Pass the localized message or localization key through the existing error-display path instead of hardcoding the user-facing English text in the client.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread src/services/clients/claude/index.mjs Outdated
@greptile-apps

greptile-apps Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues were found.

Summary

Claude Web now prefers an organization with chat access and keeps the first organization as a fallback.

  • Claude Web loads conversations from an organization with chat access.

Reviews (3) · Last reviewed commit: "Report the raw conversations response in..." · Reviewed by Greptile

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Prefer a chat-capable organization in Claude.init() — organizations[0].uuid becomes organizations.find((org) => org.capabilities?.includes('chat')) || organizations[0], so accounts whose first organization is the API-only one no longer target an org that claude.ai denies chat access to. The || organizations[0] fallback preserves prior behavior when capabilities is absent.
  • Fail readably when conversations are denied — getConversations() now throws new Error(json?.error?.message || 'failed to load conversations') for non-array bodies instead of letting json.map raise a TypeError. This also makes startConversation's this.recent_conversations.map(...) safe, since recent_conversations can no longer be set to a non-array.
  • Test-runner resolution — the fetch-sse import gains its .mjs extension so the client loads under node:test. Webpack resolves both forms, so no bundle change.
  • New unit tests — tests/unit/services/clients/claude.test.mjs covers chat-org preference, fallback without chat, and the denied-conversations error message via a fetch mock that rejects unexpected routes.

I verified the new tests pass (3/3) with the browser shim, and eslint/prettier are clean on both files. The change is well-scoped to Claude Web and does not alter behavior for single-organization accounts or those whose first organization already reports chat.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply to a comment to ask cubic a question or push back. It learns from your replies.

View guided diff | Re-trigger cubic

Comment thread tests/unit/services/clients/claude.test.mjs Outdated
Comment thread src/services/clients/claude/index.mjs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix preserves fallback behavior, includes targeted regression coverage, and has no identified blocking issues.

No open issues 🎉

What changed in this PR

Fixes Claude Web initialization for accounts linked to Anthropic Console by selecting an organization with chat access rather than an API-only organization.

Changes:

  • Prefer an organization with chat capability, retaining the first-organization fallback.
  • Report service errors when conversation responses are not arrays.
  • Add regression tests and an explicit .mjs import for Node test compatibility.
File Description
tests/​unit/​services/​clients/​claude.test.mjs Tests chat organization selection, fallback behavior, and error propagation.
src/​services/​clients/​claude/​index.mjs Updates organization selection, validates conversation responses, and fixes the import extension.

Review effort: Balanced

With a single organization the fallback test could not tell whether
init() picks the first entry. Add a second organization without chat
capability so the assertion proves the first one is used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

The delta since the prior pullfrog review (a031c94) is confined to the Claude client's unit tests; the source files are unchanged.

  • Strengthened the no-chat fallback test — the test is renamed to "falls back to the first organization when none has chat capability" and now supplies two non-chat organizations (first-org with no capabilities, second-org with ['api']), so it proves the || organizations[0] fallback selects the first organization rather than merely the only one. This also addresses cubic's P2 ordering finding.

Verified the suite still passes (node --import ./tests/setup/browser-shim.mjs --test tests/unit/services/clients/claude.test.mjs → 3/3).

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@PeterDaveHello
PeterDaveHello requested a balanced review from Copilot October 27, 2026 16:36
@PeterDaveHello

Copy link
Copy Markdown
Member

/agentic_review

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 23dd3f8

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrow fix addresses the reported failure, preserves fallback behavior, and includes focused regression coverage with no blocking issues identified.

No open issues 🎉

Review effort: Balanced

When claude.ai returns a non-list without an error message, show the
response itself instead of a new hard-coded English message, so no
untranslated user-facing string is added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

The delta since the prior pullfrog review (23dd3f8) is small and well-covered.

  • Raw response in the non-array error — getConversations() now falls back to JSON.stringify(json) instead of the hardcoded 'failed to load conversations', so arbitrary non-array bodies surface their actual content rather than a fixed label. JSON.stringify is safe in this path: response.json() cannot return undefined, and a parsed body cannot be circular.
  • New test for the raw-response path — a fourth test feeds { data: [] } and asserts the thrown message is '{"data":[]}', exercising the branch the commit added.

Verified the suite passes (node --import ./tests/setup/browser-shim.mjs --test tests/unit/services/clients/claude.test.mjs → 4/4). The commit_id below reflects 462a0e8.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants