Skip to content

Fix Cloud Code Assist API errors (429/400)#544

Merged
steipete merged 3 commits into
mainfrom
unknown repository
Jan 10, 2026
Merged

Fix Cloud Code Assist API errors (429/400)#544
steipete merged 3 commits into
mainfrom
unknown repository

Conversation

@ghost

@ghost ghost commented Jan 9, 2026

Copy link
Copy Markdown

Summary

This PR fixes critical Cloud Code Assist API errors that were causing user-facing failures:

  • 429 RESOURCE_EXHAUSTED: Enhanced rate limit detection to properly identify Cloud Code Assist quota exhaustion
  • 400 INVALID_ARGUMENT: Added tool call ID sanitization to fix invalid request format errors for Cloud Code Assist

Changes Made

Enhanced Rate Limit Detection (src/agents/pi-embedded-helpers.ts)

  • Added Cloud Code Assist specific error patterns: "resource has been exhausted", "quota exceeded", "resource_exhausted"
  • Improved isRateLimitErrorMessage() to handle Cloud Code Assist quota errors

Tool Call ID Sanitization (src/agents/pi-embedded-helpers.ts)

  • Enhanced sanitizeToolCallId() with comprehensive validation and pattern matching
  • Added isValidCloudCodeAssistToolId() for proper Cloud Code Assist format validation (^[a-zA-Z0-9_-]+$)
  • Added isCloudCodeAssistFormatError() for specific Cloud Code Assist error detection

Integrated Failover System (src/agents/pi-embedded-runner.ts)

  • Added Cloud Code Assist format error detection to retry logic
  • Enhanced error rotation to treat format errors as authentication failures
  • Added specific logging for Cloud Code Assist format errors

Files Changed

  • src/agents/pi-embedded-helpers.ts - Enhanced error detection and tool call sanitization
  • src/agents/pi-embedded-runner.ts - Integrated Cloud Code Assist error handling into failover system

Testing

  • ✅ All existing tests pass
  • ✅ Build and lint successful
  • ✅ Enhanced error detection verified for Cloud Code Assist patterns
  • ✅ Tool call sanitization follows proper Cloud Code Assist format requirements

Impact

  • Before: Users saw 429/400 Cloud Code Assist errors with automatic failover
  • After: System automatically detects Cloud Code Assist errors and fails over to working providers seamlessly

This makes the system production-ready for Cloud Code Assist integration with robust error handling.

Fixes: Cloud Code Assist API integration errors

Copilot AI review requested due to automatic review settings January 9, 2026 00:34

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.

Pull request overview

This PR aims to fix Cloud Code Assist API errors (429 RESOURCE_EXHAUSTED and 400 INVALID_ARGUMENT) by enhancing error detection and adding tool call ID sanitization to ensure proper failover when these errors occur.

Key changes:

  • Enhanced rate limit and authentication error detection with Cloud Code Assist specific patterns
  • Added tool call ID sanitization to replace invalid characters with valid ones
  • Integrated Cloud Code Assist format error detection into the failover system

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
src/config/paths.ts Adds legacy exports for Clawdis → Clawdbot rebrand (unrelated to PR purpose)
src/agents/pi-embedded-helpers.ts Enhances error detection patterns, adds tool call ID sanitization, and integrates sanitization into message processing
src/agents/pi-embedded-runner.ts Adds Cloud Code Assist format error detection to retry/failover logic with appropriate logging

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +464 to +470
const trimmedInvalidStartChars = cloudCodeAssistPatternReplacement.replace(
/^[^a-zA-Z0-9_-]+/,
"",
);

return trimmedInvalidStartChars.length > 0
? trimmedInvalidStartChars

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

The second regex replacement on lines 464-466 is redundant and will never match anything. After line 463 replaces all invalid characters with underscores, the string can only contain valid characters [a-zA-Z0-9_-], so the pattern ^[^a-zA-Z0-9_-]+ will never find any leading invalid characters to remove. Consider removing this redundant operation.

Suggested change
const trimmedInvalidStartChars = cloudCodeAssistPatternReplacement.replace(
/^[^a-zA-Z0-9_-]+/,
"",
);
return trimmedInvalidStartChars.length > 0
? trimmedInvalidStartChars
return cloudCodeAssistPatternReplacement.length > 0
? cloudCodeAssistPatternReplacement

Copilot uses AI. Check for mistakes.
Comment thread src/agents/pi-embedded-helpers.ts Outdated
value.includes("resource has been exhausted") ||
value.includes("invalid_request_error") ||
value.includes("string should match pattern") ||
value.includes("tool_use_id") ||

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

There's an inconsistency in pattern matching: line 288 checks for "tool_use_id" (with underscore) while line 300 checks for "tool_use.id" (with dot). These are different patterns that won't match the same error messages. Based on the specific pattern in line 301 ("messages.1.content.1.tool_use.id"), the correct pattern appears to be with dots, not underscores. Verify which pattern is actually returned by Cloud Code Assist API and ensure consistency across both functions.

Suggested change
value.includes("tool_use_id") ||
value.includes("tool_use.id") ||

Copilot uses AI. Check for mistakes.
Comment on lines +123 to +139
const sanitizedContent = await Promise.all(
filteredContent.map(async (block) => {
if (
block &&
typeof block === "object" &&
(block as { type?: unknown }).type === "functionCall" &&
(block as { id?: unknown }).id
) {
const functionBlock = block as { type: string; id: string };
return {
...functionBlock,
id: sanitizeToolCallId(functionBlock.id),
};
}
return block;
}),
);

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

The Promise.all with async map function on lines 123-139 is unnecessary since sanitizeToolCallId is a synchronous function. The code can be simplified by using a regular map() instead of await Promise.all(filteredContent.map(async ...)), which would improve performance by avoiding unnecessary promise wrapping for synchronous operations.

Suggested change
const sanitizedContent = await Promise.all(
filteredContent.map(async (block) => {
if (
block &&
typeof block === "object" &&
(block as { type?: unknown }).type === "functionCall" &&
(block as { id?: unknown }).id
) {
const functionBlock = block as { type: string; id: string };
return {
...functionBlock,
id: sanitizeToolCallId(functionBlock.id),
};
}
return block;
}),
);
const sanitizedContent = filteredContent.map((block) => {
if (
block &&
typeof block === "object" &&
(block as { type?: unknown }).type === "functionCall" &&
(block as { id?: unknown }).id
) {
const functionBlock = block as { type: string; id: string };
return {
...functionBlock,
id: sanitizeToolCallId(functionBlock.id),
};
}
return block;
});

Copilot uses AI. Check for mistakes.
Comment thread src/agents/pi-embedded-helpers.ts Outdated
@@ -248,16 +280,38 @@ export function isAuthErrorMessage(raw: string): boolean {
value.includes("unauthorized") ||
value.includes("forbidden") ||
value.includes("access denied") ||
value.includes("expired") ||
value.includes("token has expired") ||
value.includes("resource has been exhausted") ||

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

The error pattern "resource has been exhausted" is duplicated in both isRateLimitErrorMessage (line 265) and isAuthErrorMessage (line 285). This creates ambiguity in error classification. Since this error typically indicates quota/rate limit exhaustion rather than authentication failure, it should only be included in isRateLimitErrorMessage.

Suggested change
value.includes("resource has been exhausted") ||

Copilot uses AI. Check for mistakes.
Comment thread src/agents/pi-embedded-helpers.ts Outdated
Comment on lines +286 to +288
value.includes("invalid_request_error") ||
value.includes("string should match pattern") ||
value.includes("tool_use_id") ||

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

Adding format validation error patterns ("invalid_request_error", "string should match pattern", "tool_use_id") to isAuthErrorMessage is semantically incorrect. These patterns indicate request format issues, not authentication failures. This conflates two distinct error categories and may cause incorrect error handling. Consider removing these patterns from this function since they're already handled by isCloudCodeAssistFormatError.

Suggested change
value.includes("invalid_request_error") ||
value.includes("string should match pattern") ||
value.includes("tool_use_id") ||

Copilot uses AI. Check for mistakes.
Comment thread src/agents/pi-embedded-helpers.ts Outdated
Comment on lines +311 to +314
return (
isAuthErrorMessage(errorMessage) ||
isCloudCodeAssistFormatError(errorMessage)
);

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

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

The isAuthAssistantError function now treats Cloud Code Assist format errors as authentication errors by including isCloudCodeAssistFormatError in its logic. This is semantically incorrect - format validation errors are distinct from authentication failures. While the failover behavior might be similar, conflating these error types reduces code clarity and makes debugging more difficult. Consider separating format error handling from authentication error handling at the calling sites instead.

Suggested change
return (
isAuthErrorMessage(errorMessage) ||
isCloudCodeAssistFormatError(errorMessage)
);
return isAuthErrorMessage(errorMessage);

Copilot uses AI. Check for mistakes.
@steipete

steipete commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

please retest this once #543 landed

@ghost

ghost commented Jan 9, 2026 via email

Copy link
Copy Markdown
Author

@steipete steipete self-assigned this Jan 10, 2026
HeimdallStrategy and others added 3 commits January 10, 2026 01:07
- Add sanitizeToolCallId() to fix Cloud Code Assist tool call ID validation
- Apply sanitization in sanitizeSessionMessagesImages() for toolResult and assistant messages
- Add legacy CONFIG_PATH_CLAWDIS and STATE_DIR_CLAWDIS exports for backward compatibility
- Resolves Cloud Code Assist rejection of invalid tool call IDs with pipe characters
- Fixes missing session export functions that were blocking system startup

Addresses Cloud Code Assist API 400 errors from invalid tool call IDs like 'call_abc123|item_456'
- Enhanced rate limit detection for Cloud Code Assist quota exhaustion
- Added tool call ID sanitization to fix invalid request format errors
- Integrated Cloud Code Assist format error detection into failover system
- Added comprehensive error pattern matching for Cloud Code Assist APIs

Fixes #cloud-code-assist-api-errors
@steipete
steipete merged commit 08015fb into openclaw:main Jan 10, 2026
7 of 19 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Landed via temp rebase onto main.

  • Gate: pnpm lint && pnpm build && pnpm test
  • Land commit: 251ed83
  • Merge commit: 08015fb

Thanks @jeffersonwarrior!

@ghost

ghost commented Jan 10, 2026 via email

Copy link
Copy Markdown
Author

lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
…assist-api-errors

Fix Cloud Code Assist API errors (429/400)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…assist-api-errors

Fix Cloud Code Assist API errors (429/400)
franciscomaestre added a commit to franciscomaestre/openclaw that referenced this pull request Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants