Skip to content

feat: error handling added in integrations with their test cases#155

Merged
akshaydeo merged 1 commit intomainfrom
07-10-feat_error_handling_added_for_transport_integrations_with_their_test_cases
Jul 10, 2025
Merged

feat: error handling added in integrations with their test cases#155
akshaydeo merged 1 commit intomainfrom
07-10-feat_error_handling_added_for_transport_integrations_with_their_test_cases

Conversation

@Pratham-Mishra04
Copy link
Copy Markdown
Collaborator

Add Provider Information to BifrostError for Improved Error Propagation

This PR enhances error handling in Bifrost by adding provider information to BifrostError objects and ensuring proper error propagation through the system. The changes enable more accurate error reporting when requests fail, making it easier to identify which provider encountered an issue.

Key improvements:

  • Added a Provider field to the BifrostError struct to track which provider generated the error
  • Set the provider field at all error creation points in the request flow
  • Implemented provider-specific error converters for each integration (OpenAI, Anthropic, Google, LiteLLM)
  • Added proper error propagation in the HTTP transport layer
  • Enhanced error handling for cancelled requests
  • Added comprehensive error handling tests for all integrations

These changes ensure that when a request fails, the error response will accurately reflect which provider encountered the issue, with the error formatted according to that provider's API conventions. This is particularly important for applications that need to handle errors differently based on the provider that generated them.

The PR also adds a new test category for error handling, verifying that invalid role errors are properly detected and propagated through the system.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 10, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced error responses for Anthropic, OpenAI, and Google integrations to provide provider-specific error formats.
    • Error responses now include provider identity for improved traceability.
  • Bug Fixes

    • Improved error handling for invalid role scenarios across Anthropic, OpenAI, Google, and LiteLLM integrations.
  • Documentation

    • Updated integration test documentation to include a new "Error Handling" test category with instructions.
  • Tests

    • Added new integration tests to verify error handling and propagation for invalid role errors across all supported providers.
    • Introduced shared test utilities for validating error responses and propagation.

Walkthrough

This update introduces explicit assignment of the Provider field to BifrostError instances, ensuring error provenance is tracked. It adds provider-specific error converters to HTTP transport routes, implements integration-specific error response structures, and expands the test suite with new error-handling tests and validation utilities for invalid role scenarios across multiple integrations.

Changes

File(s) Change Summary
core/bifrost.go Assigns Provider field in BifrostError for all main request methods.
core/schemas/bifrost.go Adds Provider field to BifrostError struct.
tests/transports-integrations/README.md Updates test documentation to include new "Error Handling" category and usage instructions.
tests/transports-integrations/tests/integrations/test_anthropic.py Adds test for invalid role error handling and propagation in Anthropic integration.
tests/transports-integrations/tests/integrations/test_google.py Adds test for invalid role error handling and propagation in Google GenAI integration.
tests/transports-integrations/tests/integrations/test_litellm.py Adds test for invalid role error handling and propagation in LiteLLM integration.
tests/transports-integrations/tests/integrations/test_openai.py Adds test for invalid role error handling and propagation in OpenAI integration.
tests/transports-integrations/tests/utils/common.py Adds error assertion utilities, test data for invalid roles, and new test category for error handling.
transports/bifrost-http/integrations/anthropic/router.go Adds ErrorConverter to Anthropic route for provider-specific error formatting.
transports/bifrost-http/integrations/anthropic/types.go Introduces Anthropic error response structs and function to convert BifrostError to Anthropic format.
transports/bifrost-http/integrations/genai/router.go Adds ErrorConverter to GenAI route for Gemini-specific error formatting.
transports/bifrost-http/integrations/genai/types.go Introduces Gemini error response structs and function to convert BifrostError to Gemini format.
transports/bifrost-http/integrations/litellm/router.go Adds error converter function for provider-specific error responses in LiteLLM router.
transports/bifrost-http/integrations/openai/router.go Adds ErrorConverter to OpenAI route for OpenAI-specific error formatting.
transports/bifrost-http/integrations/openai/types.go Introduces OpenAI error response structs and function to convert BifrostError to OpenAI format.
transports/bifrost-http/integrations/utils.go Adds ErrorConverter type, makes it mandatory in route configs, and updates error handling to use converters for all integrations.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HTTP Router
    participant Bifrost Core
    participant Provider
    participant ErrorConverter

    Client->>HTTP Router: Send request (e.g., chat completion)
    HTTP Router->>Bifrost Core: Forward request
    Bifrost Core->>Provider: Call provider API
    Provider-->>Bifrost Core: Return error (with Provider set)
    Bifrost Core-->>HTTP Router: Return BifrostError (with Provider)
    HTTP Router->>ErrorConverter: Convert BifrostError to integration-specific error
    ErrorConverter-->>HTTP Router: Integration-specific error response
    HTTP Router-->>Client: Send formatted error response
Loading

Possibly related PRs

Suggested reviewers

  • danpiths
  • akshaydeo

Poem

In the warren of code, where errors might hide,
Now each one wears its provider with pride.
With converters in tow, responses are neat,
Integration-specific, no easy defeat!
Tests hop along, checking roles gone astray—
A rabbit’s delight on this debugging day!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 07-10-feat_error_handling_added_for_transport_integrations_with_their_test_cases

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Pratham-Mishra04 Pratham-Mishra04 marked this pull request as ready for review July 10, 2025 18:02
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2304b3 and 91ed810.

📒 Files selected for processing (16)
  • core/bifrost.go (9 hunks)
  • core/schemas/bifrost.go (1 hunks)
  • tests/transports-integrations/README.md (3 hunks)
  • tests/transports-integrations/tests/integrations/test_anthropic.py (2 hunks)
  • tests/transports-integrations/tests/integrations/test_google.py (2 hunks)
  • tests/transports-integrations/tests/integrations/test_litellm.py (2 hunks)
  • tests/transports-integrations/tests/integrations/test_openai.py (2 hunks)
  • tests/transports-integrations/tests/utils/common.py (3 hunks)
  • transports/bifrost-http/integrations/anthropic/router.go (1 hunks)
  • transports/bifrost-http/integrations/anthropic/types.go (2 hunks)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/litellm/router.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (2 hunks)
  • transports/bifrost-http/integrations/utils.go (5 hunks)
🧰 Additional context used
🧠 Learnings (17)
📓 Common learnings
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#84
File: transports/bifrost-http/main.go:2-2
Timestamp: 2025-06-15T16:05:13.489Z
Learning: For the Bifrost project, HTTP transport integration routers for new providers (like Mistral and Ollama) are implemented in separate PRs from the core provider support, following a focused PR strategy.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#150
File: transports/bifrost-http/lib/store.go:370-466
Timestamp: 2025-07-09T04:58:08.229Z
Learning: Pratham-Mishra04 prefers not to add logging or error handling for unreachable code paths in the Bifrost project. When provider types or similar entities are predefined in the system, defensive programming like logging in default cases is considered unnecessary overhead.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/providers/mistral.go:96-101
Timestamp: 2025-06-15T13:50:41.418Z
Learning: In the Bifrost project, when a provider doesn't support a specific operation (like text completion), the IsBifrostError flag should be set to false to mark it as a provider-level error rather than a Bifrost framework error. This is intentional design for unsupported operations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:89-119
Timestamp: 2025-06-10T11:00:02.875Z
Learning: In the Bifrost OpenAI integration (transports/bifrost-http/integrations/openai/types.go), the convertOpenAIContent function currently only handles the last image URL when multiple images are present in a content array. The user Pratham-Mishra04 has acknowledged this limitation and indicated it's part of a larger architectural issue that will be addressed comprehensively later, rather than with piecemeal fixes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#152
File: transports/bifrost-http/plugins/logging/utils.go:378-399
Timestamp: 2025-07-10T13:44:14.471Z
Learning: In the Bifrost logging plugin (transports/bifrost-http/plugins/logging/utils.go), Pratham-Mishra04 prefers not to add error handling for JSON unmarshaling operations, considering logging not very critical and being confident that JSON marshalling won't fail in practice.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/providers/bedrock.go:241-252
Timestamp: 2025-06-04T09:07:20.867Z
Learning: In the Bifrost codebase, when working with AWS Bedrock provider authentication, the preference is to let AWS handle access key validation naturally rather than adding preemptive checks for empty/blank access keys. This allows AWS to provide its own authentication error messages which can be more informative than custom validation errors.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#152
File: transports/bifrost-http/plugins/logging/utils.go:94-111
Timestamp: 2025-07-10T13:44:23.255Z
Learning: Pratham-Mishra04 prefers not to add error handling for JSON marshaling operations in the Bifrost logging plugin (transports/bifrost-http/plugins/logging/utils.go) because logging is not critical functionality and the structured schema data being marshaled is unlikely to fail. They accept the risk of not handling json.Marshal errors in logging contexts to keep the code simple.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#141
File: core/bifrost.go:198-272
Timestamp: 2025-07-08T18:30:08.258Z
Learning: Pratham-Mishra04 follows a pattern of implementing core functionality first and deferring non-critical improvements (like race condition fixes, optimizations) to later PRs. This is a reasonable development approach that prioritizes getting the main feature working before addressing edge cases.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/providers/mistral.go:168-170
Timestamp: 2025-06-15T14:24:49.882Z
Learning: In the Bifrost codebase, performance is prioritized over defensive copying for HTTP service operations. Specifically, shallow slice assignments in provider response handling are acceptable due to object pool reset patterns and JSON unmarshaling behavior that minimize practical data corruption risks.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/config/account.go:55-101
Timestamp: 2025-06-16T04:25:00.816Z
Learning: In the Bifrost test account implementation, the user prefers to let Bifrost itself handle missing API key errors rather than adding early validation in the GetKeysForProvider method.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/provider.go:148-148
Timestamp: 2025-06-04T03:57:50.981Z
Learning: Breaking changes in the Bifrost codebase are managed by first merging and tagging core schema changes, then updating dependent code references in subsequent steps after the core version is released.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:358-388
Timestamp: 2025-06-04T05:37:59.699Z
Learning: User Pratham-Mishra04 prefers not to extract small code duplications (around 2 lines) into helper functions, considering the overhead not worth it for such minor repetition.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#102
File: README.md:62-66
Timestamp: 2025-06-19T17:03:03.639Z
Learning: Pratham-Mishra04 prefers using the implicit 'latest' tag for the maximhq/bifrost Docker image rather than pinning to specific versions.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#143
File: core/mcp.go:155-196
Timestamp: 2025-07-08T15:33:47.698Z
Learning: Pratham-Mishra04 prefers not to add explanatory comments for obvious code patterns, such as the unlock/lock strategy around network I/O operations, considering them self-explanatory to experienced developers.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#138
File: docs/usage/go-package/mcp.md:408-412
Timestamp: 2025-07-01T12:40:08.576Z
Learning: Pratham-Mishra04 is okay with keeping bullet list formatting that uses colons after dashes in markdown documentation, even if it triggers linter warnings, preferring functionality over strict formatting rules.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#148
File: transports/bifrost-http/lib/store.go:880-910
Timestamp: 2025-07-08T17:14:21.544Z
Learning: Pratham-Mishra04 prefers resilient system design where missing environment variables for MCP connections should not cause complete system failure. The system should continue processing other MCP connections even when some fail, maintaining partial functionality rather than implementing fail-fast behavior.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#138
File: transports/README.md:26-28
Timestamp: 2025-07-01T12:45:06.906Z
Learning: Pratham-Mishra04 prefers keeping documentation examples simple and concise, trusting users to handle production-specific considerations like version pinning themselves rather than cluttering examples with additional notes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#148
File: transports/bifrost-http/lib/store.go:1081-1098
Timestamp: 2025-07-08T17:16:50.811Z
Learning: Pratham-Mishra04 prefers practical redaction approaches over theoretical security improvements when the threat model is low-risk, such as admin-only interfaces in the Bifrost project. Fixed-length redaction is acceptable when only trusted administrators will see the redacted values.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#144
File: transports/bifrost-http/plugins/logging/utils.go:286-292
Timestamp: 2025-07-08T16:40:59.098Z
Learning: Pratham-Mishra04 prefers to keep simpler error handling patterns when errors are unlikely to occur in practice, such as safety checks in BadgerDB iterations where item.Value() is called on valid items. The user considers the overhead of explicit error handling not worth it in such scenarios.
core/schemas/bifrost.go (12)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/schemas/bifrost.go:186-190
Timestamp: 2025-06-15T14:18:32.703Z
Learning: In core/schemas/bifrost.go, the ToolChoice UnmarshalJSON validation intentionally only checks for empty Type fields and lets providers handle validation of specific tool choice values. This architectural decision keeps schema validation focused on structure while allowing provider-specific semantic validation.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/schemas/bifrost.go:20-23
Timestamp: 2025-06-18T15:16:23.127Z
Learning: In the Bifrost project, BifrostConfig struct is never marshaled/unmarshaled, so serialization tags (json, yaml) are not needed for its fields.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#144
File: transports/bifrost-http/handlers/providers.go:45-49
Timestamp: 2025-07-08T16:50:27.699Z
Learning: In the Bifrost project, breaking API changes are acceptable when features are not yet public. This applies to scenarios like changing struct fields from pointer to non-pointer types in request/response structures for unreleased features.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:223-231
Timestamp: 2025-06-10T11:06:06.670Z
Learning: The OpenAI `name` field on messages cannot be preserved when converting to Bifrost format because the `schemas.BifrostMessage` struct in bifrost/core does not support a Name field. This is a known limitation of the Bifrost core schema design.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/provider.go:148-148
Timestamp: 2025-06-04T03:57:50.981Z
Learning: Breaking changes in the Bifrost codebase are managed by first merging and tagging core schema changes, then updating dependent code references in subsequent steps after the core version is released.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/providers/mistral.go:96-101
Timestamp: 2025-06-15T13:50:41.418Z
Learning: In the Bifrost project, when a provider doesn't support a specific operation (like text completion), the IsBifrostError flag should be set to false to mark it as a provider-level error rather than a Bifrost framework error. This is intentional design for unsupported operations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#152
File: transports/bifrost-http/plugins/logging/utils.go:94-111
Timestamp: 2025-07-10T13:44:23.255Z
Learning: Pratham-Mishra04 prefers not to add error handling for JSON marshaling operations in the Bifrost logging plugin (transports/bifrost-http/plugins/logging/utils.go) because logging is not critical functionality and the structured schema data being marshaled is unlikely to fail. They accept the risk of not handling json.Marshal errors in logging contexts to keep the code simple.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
transports/bifrost-http/integrations/anthropic/router.go (9)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:0-0
Timestamp: 2025-06-04T05:44:09.141Z
Learning: For the Anthropic provider in core/providers/anthropic.go, it's acceptable to pass potentially malformed messages with invalid roles because Anthropic's API will return suitable error responses for role issues, eliminating the need for additional validation logging.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:526-550
Timestamp: 2025-06-04T09:29:46.287Z
Learning: In core/providers/anthropic.go, the content field in formattedMessages is always of type []interface{} because it's explicitly constructed that way upstream in the prepareAnthropicChatRequest function. Defensive type casting for multiple types is not needed since the type is guaranteed by the construction logic.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
transports/bifrost-http/integrations/genai/router.go (11)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:22-56
Timestamp: 2025-06-16T14:50:46.859Z
Learning: In the Google GenAI integration at transports/bifrost-http/integrations/genai/types.go, the manual URL-safe base64 decoding implementation (converting - to +, _ to /, and adding padding) is required because base64.RawURLEncoding.DecodeString fails for the specific url encoded bytes format being handled.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#64
File: transports/bifrost-http/integrations/genai/types.go:273-313
Timestamp: 2025-06-09T16:35:26.914Z
Learning: In convertGenerationConfigToParams method in transports/bifrost-http/integrations/genai/types.go, pre-allocating the ExtraParams map is preferred over lazy allocation because the method has multiple potential ExtraParams assignments, making the computational overhead of conditional checks exceed the memory savings of an empty map.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:44:42.893Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to return a validation error rather than setting a default role value. This represents a design preference for strict input validation over silent error correction.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#75
File: transports/bifrost-http/integrations/genai/types.go:109-117
Timestamp: 2025-06-14T08:54:58.137Z
Learning: In the Gemini/GenAI integration (transports/bifrost-http/integrations/genai/types.go), function calls don't have IDs, only names. Therefore, using the function name as ToolCallID is intentional and correct behavior, as Gemini's API doesn't provide call IDs.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
tests/transports-integrations/README.md (9)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#149
File: docs/contributing/README.md:22-27
Timestamp: 2025-07-08T18:12:13.590Z
Learning: In the Bifrost project, the tests directory structure has `tests/core-providers/` and `tests/transports-integrations/` as sibling directories. From `tests/core-providers/`, the correct relative path to reach `tests/transports-integrations/` is `../transports-integrations/`, not `../../tests/transports-integrations/`.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/provider.go:148-148
Timestamp: 2025-06-04T03:57:50.981Z
Learning: Breaking changes in the Bifrost codebase are managed by first merging and tagging core schema changes, then updating dependent code references in subsequent steps after the core version is released.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#84
File: transports/bifrost-http/main.go:2-2
Timestamp: 2025-06-15T16:05:13.489Z
Learning: For the Bifrost project, HTTP transport integration routers for new providers (like Mistral and Ollama) are implemented in separate PRs from the core provider support, following a focused PR strategy.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#103
File: .github/workflows/transport-dependency-update.yml:53-75
Timestamp: 2025-06-20T16:21:18.912Z
Learning: In the bifrost repository's transport dependency update workflow, when updating the core dependency to a new version using `go get`, the go.mod and go.sum files will always change in normal operation, making the safety check for changes more of a defensive programming practice rather than handling a common scenario.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#82
File: tests/transports-integrations/tests/integrations/test_litellm.py:97-115
Timestamp: 2025-06-16T09:16:15.634Z
Learning: In the Bifrost integration tests, the user prefers tests to fail hard when API keys are missing rather than using @skip_if_no_api_key decorators for graceful skipping. This applies to LiteLLM tests that depend on OpenAI API keys.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/automatic_function_calling.go:22-22
Timestamp: 2025-06-16T04:55:11.886Z
Learning: In the Bifrost test suite (tests/core-providers), parallel tests using t.Parallel() are not being implemented currently. The team plans to add parallel test execution in future enhancements.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#144
File: transports/bifrost-http/handlers/providers.go:45-49
Timestamp: 2025-07-08T16:50:27.699Z
Learning: In the Bifrost project, breaking API changes are acceptable when features are not yet public. This applies to scenarios like changing struct fields from pointer to non-pointer types in request/response structures for unreleased features.
tests/transports-integrations/tests/integrations/test_openai.py (7)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#82
File: tests/transports-integrations/tests/integrations/test_litellm.py:97-115
Timestamp: 2025-06-16T09:16:15.634Z
Learning: In the Bifrost integration tests, the user prefers tests to fail hard when API keys are missing rather than using @skip_if_no_api_key decorators for graceful skipping. This applies to LiteLLM tests that depend on OpenAI API keys.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:264-285
Timestamp: 2025-06-10T12:58:45.501Z
Learning: In the Bifrost OpenAI integration, tool calls should be allowed on any message role (not just assistant messages) and the downstream provider should handle validation. Users passing tool calls to non-assistant messages is considered deliberate behavior that should be preserved.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:89-119
Timestamp: 2025-06-10T11:00:02.875Z
Learning: In the Bifrost OpenAI integration (transports/bifrost-http/integrations/openai/types.go), the convertOpenAIContent function currently only handles the last image URL when multiple images are present in a content array. The user Pratham-Mishra04 has acknowledged this limitation and indicated it's part of a larger architectural issue that will be addressed comprehensively later, rather than with piecemeal fixes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:129-145
Timestamp: 2025-06-10T11:12:26.883Z
Learning: Anthropic API does not support tool roles and images can only be present in user messages, not assistant or tool messages. Therefore, in Anthropic integration code, image content should always be assigned to UserMessage regardless of any other considerations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/bedrock.go:565-571
Timestamp: 2025-06-04T05:50:15.021Z
Learning: AWS Bedrock Converse API does not support message role "tool". Tool results must use role "user" with a specific "toolResult" content structure containing "toolUseId" and "content" fields. This differs from other providers that may accept "tool" role.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:03:26.997Z
Learning: In Anthropic API message format, tool_result content blocks are sent by users in response to assistant tool calls, while image content blocks are typically sent in initial user messages. These content types follow different conversation flows and wouldn't naturally appear together in a single message, making defensive guards against multiple embedded message types unnecessary.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#74
File: core/providers/bedrock.go:909-916
Timestamp: 2025-06-11T15:05:45.355Z
Learning: In Bedrock chat responses (`core/providers/bedrock.go`), image content blocks are only possible in messages with the `user` role; assistant and tool messages will never contain image blocks.
tests/transports-integrations/tests/integrations/test_anthropic.py (5)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:0-0
Timestamp: 2025-06-04T05:44:09.141Z
Learning: For the Anthropic provider in core/providers/anthropic.go, it's acceptable to pass potentially malformed messages with invalid roles because Anthropic's API will return suitable error responses for role issues, eliminating the need for additional validation logging.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:129-145
Timestamp: 2025-06-10T11:12:26.883Z
Learning: Anthropic API does not support tool roles and images can only be present in user messages, not assistant or tool messages. Therefore, in Anthropic integration code, image content should always be assigned to UserMessage regardless of any other considerations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:264-285
Timestamp: 2025-06-10T12:58:45.501Z
Learning: In the Bifrost OpenAI integration, tool calls should be allowed on any message role (not just assistant messages) and the downstream provider should handle validation. Users passing tool calls to non-assistant messages is considered deliberate behavior that should be preserved.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/bedrock.go:565-571
Timestamp: 2025-06-04T05:50:15.021Z
Learning: AWS Bedrock Converse API does not support message role "tool". Tool results must use role "user" with a specific "toolResult" content structure containing "toolUseId" and "content" fields. This differs from other providers that may accept "tool" role.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:261-278
Timestamp: 2025-06-09T17:12:55.222Z
Learning: Anthropic's API consistently returns tool_choice enum values in lowercase only ("auto", "none", "any", "tool"), so case normalization is not needed when processing these values in the Anthropic integration layer.
tests/transports-integrations/tests/integrations/test_litellm.py (4)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#82
File: tests/transports-integrations/tests/integrations/test_litellm.py:97-115
Timestamp: 2025-06-16T09:16:15.634Z
Learning: In the Bifrost integration tests, the user prefers tests to fail hard when API keys are missing rather than using @skip_if_no_api_key decorators for graceful skipping. This applies to LiteLLM tests that depend on OpenAI API keys.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:129-145
Timestamp: 2025-06-10T11:12:26.883Z
Learning: Anthropic API does not support tool roles and images can only be present in user messages, not assistant or tool messages. Therefore, in Anthropic integration code, image content should always be assigned to UserMessage regardless of any other considerations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:264-285
Timestamp: 2025-06-10T12:58:45.501Z
Learning: In the Bifrost OpenAI integration, tool calls should be allowed on any message role (not just assistant messages) and the downstream provider should handle validation. Users passing tool calls to non-assistant messages is considered deliberate behavior that should be preserved.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:03:26.997Z
Learning: In Anthropic API message format, tool_result content blocks are sent by users in response to assistant tool calls, while image content blocks are typically sent in initial user messages. These content types follow different conversation flows and wouldn't naturally appear together in a single message, making defensive guards against multiple embedded message types unnecessary.
transports/bifrost-http/integrations/openai/router.go (11)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:89-119
Timestamp: 2025-06-10T11:00:02.875Z
Learning: In the Bifrost OpenAI integration (transports/bifrost-http/integrations/openai/types.go), the convertOpenAIContent function currently only handles the last image URL when multiple images are present in a content array. The user Pratham-Mishra04 has acknowledged this limitation and indicated it's part of a larger architectural issue that will be addressed comprehensively later, rather than with piecemeal fixes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:22-56
Timestamp: 2025-06-16T14:50:46.859Z
Learning: In the Google GenAI integration at transports/bifrost-http/integrations/genai/types.go, the manual URL-safe base64 decoding implementation (converting - to +, _ to /, and adding padding) is required because base64.RawURLEncoding.DecodeString fails for the specific url encoded bytes format being handled.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
transports/bifrost-http/integrations/litellm/router.go (10)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#149
File: transports/bifrost-http/main.go:259-261
Timestamp: 2025-07-08T18:20:24.086Z
Learning: In transports/bifrost-http/lib/store.go, the LoadFromConfig method already handles missing config files gracefully by initializing defaults and auto-detecting providers from environment variables. It only returns errors for actual parsing/processing failures, not missing files, making log.Fatalf appropriate in main.go since real errors should terminate the program.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
tests/transports-integrations/tests/integrations/test_google.py (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:129-145
Timestamp: 2025-06-10T11:12:26.883Z
Learning: Anthropic API does not support tool roles and images can only be present in user messages, not assistant or tool messages. Therefore, in Anthropic integration code, image content should always be assigned to UserMessage regardless of any other considerations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:264-285
Timestamp: 2025-06-10T12:58:45.501Z
Learning: In the Bifrost OpenAI integration, tool calls should be allowed on any message role (not just assistant messages) and the downstream provider should handle validation. Users passing tool calls to non-assistant messages is considered deliberate behavior that should be preserved.
core/bifrost.go (13)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/providers/mistral.go:96-101
Timestamp: 2025-06-15T13:50:41.418Z
Learning: In the Bifrost project, when a provider doesn't support a specific operation (like text completion), the IsBifrostError flag should be set to false to mark it as a provider-level error rather than a Bifrost framework error. This is intentional design for unsupported operations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#83
File: core/providers/mistral.go:168-170
Timestamp: 2025-06-15T14:24:49.882Z
Learning: In the Bifrost codebase, performance is prioritized over defensive copying for HTTP service operations. Specifically, shallow slice assignments in provider response handling are acceptable due to object pool reset patterns and JSON unmarshaling behavior that minimize practical data corruption risks.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/utils.go:169-173
Timestamp: 2025-06-09T17:33:52.234Z
Learning: The ChatCompletionRequest method in the Bifrost client follows a contract where the result parameter will never be nil if the error parameter is nil. This means when error checking passes (err == nil), the result is guaranteed to be valid and can be safely used without additional nil checks.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#84
File: core/providers/ollama.go:59-61
Timestamp: 2025-06-15T14:34:29.401Z
Learning: The `CheckAndSetDefaults()` method on `*schemas.ProviderConfig` in Go does not return any error - it has a void return type and only sets default values on the configuration struct.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
transports/bifrost-http/integrations/anthropic/types.go (15)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:526-550
Timestamp: 2025-06-04T09:29:46.287Z
Learning: In core/providers/anthropic.go, the content field in formattedMessages is always of type []interface{} because it's explicitly constructed that way upstream in the prepareAnthropicChatRequest function. Defensive type casting for multiple types is not needed since the type is guaranteed by the construction logic.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:0-0
Timestamp: 2025-06-04T05:44:09.141Z
Learning: For the Anthropic provider in core/providers/anthropic.go, it's acceptable to pass potentially malformed messages with invalid roles because Anthropic's API will return suitable error responses for role issues, eliminating the need for additional validation logging.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:11:37.867Z
Learning: In Anthropic API integration for Bifrost, messages won't contain both image and tool_result content blocks in the same message, so defensive guards against multiple embedded message structs are unnecessary in the content processing loop.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:140-146
Timestamp: 2025-06-10T13:51:52.859Z
Learning: In Bifrost core v1.0.9, ImageContent.Type was a pointer type (*string accessed via bifrost.Ptr), but in v1.0.10 it was changed to a value type (ImageContentType). When reviewing code, check the core version being used to determine the correct assignment pattern.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:03:26.997Z
Learning: In Anthropic API message format, tool_result content blocks are sent by users in response to assistant tool calls, while image content blocks are typically sent in initial user messages. These content types follow different conversation flows and wouldn't naturally appear together in a single message, making defensive guards against multiple embedded message types unnecessary.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#64
File: transports/bifrost-http/integrations/genai/types.go:383-395
Timestamp: 2025-06-09T16:26:05.777Z
Learning: In the Bifrost schema (core/schemas/bifrost.go), only UserMessage and ToolMessage structs have ImageContent fields. AssistantMessage does not have an ImageContent field and cannot contain images. The schema design intentionally limits image content to user and tool messages only.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#144
File: transports/bifrost-http/plugins/logging/utils.go:509-514
Timestamp: 2025-07-08T16:48:25.386Z
Learning: In the Bifrost logging system (transports/bifrost-http/plugins/logging/utils.go), the Content field in message structures is a struct value type, not a pointer, so it will never be nil and doesn't require nil checks. However, ContentStr within Content is a pointer and should be checked for nil.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#75
File: transports/bifrost-http/integrations/anthropic/types.go:154-160
Timestamp: 2025-06-14T04:19:06.327Z
Learning: Anthropic's API does not support images in system messages, only text content is allowed in system messages for Anthropic integrations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
transports/bifrost-http/integrations/genai/types.go (14)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#75
File: transports/bifrost-http/integrations/genai/types.go:109-117
Timestamp: 2025-06-14T08:54:58.137Z
Learning: In the Gemini/GenAI integration (transports/bifrost-http/integrations/genai/types.go), function calls don't have IDs, only names. Therefore, using the function name as ToolCallID is intentional and correct behavior, as Gemini's API doesn't provide call IDs.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:22-56
Timestamp: 2025-06-16T14:50:46.859Z
Learning: In the Google GenAI integration at transports/bifrost-http/integrations/genai/types.go, the manual URL-safe base64 decoding implementation (converting - to +, _ to /, and adding padding) is required because base64.RawURLEncoding.DecodeString fails for the specific url encoded bytes format being handled.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:526-550
Timestamp: 2025-06-04T09:29:46.287Z
Learning: In core/providers/anthropic.go, the content field in formattedMessages is always of type []interface{} because it's explicitly constructed that way upstream in the prepareAnthropicChatRequest function. Defensive type casting for multiple types is not needed since the type is guaranteed by the construction logic.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:44:42.893Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to return a validation error rather than setting a default role value. This represents a design preference for strict input validation over silent error correction.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/utils.go:169-173
Timestamp: 2025-06-09T17:33:52.234Z
Learning: The ChatCompletionRequest method in the Bifrost client follows a contract where the result parameter will never be nil if the error parameter is nil. This means when error checking passes (err == nil), the result is guaranteed to be valid and can be safely used without additional nil checks.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
transports/bifrost-http/integrations/utils.go (17)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.604Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:22-56
Timestamp: 2025-06-16T14:50:46.859Z
Learning: In the Google GenAI integration at transports/bifrost-http/integrations/genai/types.go, the manual URL-safe base64 decoding implementation (converting - to +, _ to /, and adding padding) is required because base64.RawURLEncoding.DecodeString fails for the specific url encoded bytes format being handled.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:45:48.563Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to let the downstream provider (Google GenAI) handle validation and return errors, rather than implementing validation in the bifrost layer. This represents a design preference for delegating validation to the appropriate service rather than duplicating validation logic in the proxy layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:151-155
Timestamp: 2025-06-16T14:44:42.893Z
Learning: In transports/bifrost-http/integrations/genai/types.go, when SystemInstruction has an empty role, the user prefers to return a validation error rather than setting a default role value. This represents a design preference for strict input validation over silent error correction.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/schemas/bifrost.go:20-23
Timestamp: 2025-06-18T15:16:23.127Z
Learning: In the Bifrost project, BifrostConfig struct is never marshaled/unmarshaled, so serialization tags (json, yaml) are not needed for its fields.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#152
File: transports/bifrost-http/plugins/logging/utils.go:94-111
Timestamp: 2025-07-10T13:44:23.255Z
Learning: Pratham-Mishra04 prefers not to add error handling for JSON marshaling operations in the Bifrost logging plugin (transports/bifrost-http/plugins/logging/utils.go) because logging is not critical functionality and the structured schema data being marshaled is unlikely to fail. They accept the risk of not handling json.Marshal errors in logging contexts to keep the code simple.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#152
File: transports/bifrost-http/plugins/logging/utils.go:378-399
Timestamp: 2025-07-10T13:44:14.471Z
Learning: In the Bifrost logging plugin (transports/bifrost-http/plugins/logging/utils.go), Pratham-Mishra04 prefers not to add error handling for JSON unmarshaling operations, considering logging not very critical and being confident that JSON marshalling won't fail in practice.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/utils.go:169-173
Timestamp: 2025-06-09T17:33:52.234Z
Learning: The ChatCompletionRequest method in the Bifrost client follows a contract where the result parameter will never be nil if the error parameter is nil. This means when error checking passes (err == nil), the result is guaranteed to be valid and can be safely used without additional nil checks.
transports/bifrost-http/integrations/openai/types.go (14)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/end_to_end_tool_calling.go:43-45
Timestamp: 2025-06-16T04:13:55.437Z
Learning: In the Bifrost codebase, errors returned from client methods like ChatCompletionRequest are of type BifrostError, not the standard error interface. For testing these errors, use require.Nilf instead of require.NoErrorf since BifrostError doesn't work with the standard error assertion methods.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:89-119
Timestamp: 2025-06-10T11:00:02.875Z
Learning: In the Bifrost OpenAI integration (transports/bifrost-http/integrations/openai/types.go), the convertOpenAIContent function currently only handles the last image URL when multiple images are present in a content array. The user Pratham-Mishra04 has acknowledged this limitation and indicated it's part of a larger architectural issue that will be addressed comprehensively later, rather than with piecemeal fixes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#80
File: plugins/maxim/main.go:249-264
Timestamp: 2025-06-14T06:17:54.426Z
Learning: In the BifrostError struct, the Error field is a struct (not a pointer), so accessing bifrostErr.Error.Message, bifrostErr.Error.Code, and bifrostErr.Error.Type is safe without nil checks on the Error field itself. The Code and Type fields are of type *string.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/simple_chat.go:39-41
Timestamp: 2025-06-16T04:13:42.755Z
Learning: In the Bifrost codebase, errors returned from methods like ChatCompletionRequest are of type BifrostError (a custom error type) rather than the standard Go error interface. Therefore, require.Nilf should be used for error assertions instead of require.NoErrorf.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:223-231
Timestamp: 2025-06-10T11:06:06.670Z
Learning: The OpenAI `name` field on messages cannot be preserved when converting to Bifrost format because the `schemas.BifrostMessage` struct in bifrost/core does not support a Name field. This is a known limitation of the Bifrost core schema design.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:526-550
Timestamp: 2025-06-04T09:29:46.287Z
Learning: In core/providers/anthropic.go, the content field in formattedMessages is always of type []interface{} because it's explicitly constructed that way upstream in the prepareAnthropicChatRequest function. Defensive type casting for multiple types is not needed since the type is guaranteed by the construction logic.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#89
File: transports/bifrost-http/integrations/genai/types.go:22-56
Timestamp: 2025-06-16T14:50:46.859Z
Learning: In the Google GenAI integration at transports/bifrost-http/integrations/genai/types.go, the manual URL-safe base64 decoding implementation (converting - to +, _ to /, and adding padding) is required because base64.RawURLEncoding.DecodeString fails for the specific url encoded bytes format being handled.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#144
File: transports/bifrost-http/handlers/providers.go:45-49
Timestamp: 2025-07-08T16:50:27.699Z
Learning: In the Bifrost project, breaking API changes are acceptable when features are not yet public. This applies to scenarios like changing struct fields from pointer to non-pointer types in request/response structures for unreleased features.
Learnt from: connyay
PR: maximhq/bifrost#92
File: core/providers/utils.go:60-64
Timestamp: 2025-06-17T14:04:21.104Z
Learning: The bifrost codebase uses string alias types (like `type ContextKey string`) for context keys consistently across multiple packages including plugins/maxim/main.go and transports/bifrost-http/tracking/plugin.go. This pattern should be maintained for consistency rather than switching to the canonical struct{} approach.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/utils.go:169-173
Timestamp: 2025-06-09T17:33:52.234Z
Learning: The ChatCompletionRequest method in the Bifrost client follows a contract where the result parameter will never be nil if the error parameter is nil. This means when error checking passes (err == nil), the result is guaranteed to be valid and can be safely used without additional nil checks.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#81
File: tests/core-providers/scenarios/complete_end_to_end.go:39-41
Timestamp: 2025-06-16T04:12:05.427Z
Learning: In the Bifrost system, error returns are of type `BifrostError` rather than the standard Go `error` interface. Therefore, use `require.Nilf(t, err, ...)` instead of `require.NoError(t, err)` when checking for errors in Bifrost function calls.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
tests/transports-integrations/tests/utils/common.py (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#82
File: tests/transports-integrations/tests/integrations/test_litellm.py:97-115
Timestamp: 2025-06-16T09:16:15.634Z
Learning: In the Bifrost integration tests, the user prefers tests to fail hard when API keys are missing rather than using @skip_if_no_api_key decorators for graceful skipping. This applies to LiteLLM tests that depend on OpenAI API keys.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#94
File: core/bifrost.go:823-845
Timestamp: 2025-06-18T15:15:51.323Z
Learning: In the Bifrost project, the team prioritizes maintaining consistent error handling patterns over exposing detailed error context. All errors should be wrapped in the standard `BifrostError` structure rather than creating specific error types or exposing richer error details like exit codes or stderr output.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:264-285
Timestamp: 2025-06-10T12:58:45.501Z
Learning: In the Bifrost OpenAI integration, tool calls should be allowed on any message role (not just assistant messages) and the downstream provider should handle validation. Users passing tool calls to non-assistant messages is considered deliberate behavior that should be preserved.
🧬 Code Graph Analysis (12)
core/schemas/bifrost.go (1)
core/schemas/provider.go (1)
  • Provider (154-163)
transports/bifrost-http/integrations/anthropic/router.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ErrorConverter (32-32)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
transports/bifrost-http/integrations/anthropic/types.go (1)
  • DeriveAnthropicErrorFromBifrostError (481-506)
tests/transports-integrations/tests/integrations/test_openai.py (5)
tests/transports-integrations/tests/utils/common.py (2)
  • assert_valid_error_response (464-547)
  • assert_error_propagation (550-635)
tests/transports-integrations/tests/integrations/test_google.py (2)
  • test_12_error_handling_invalid_roles (430-440)
  • test_config (75-77)
tests/transports-integrations/tests/integrations/test_litellm.py (2)
  • test_12_error_handling_invalid_roles (347-359)
  • test_config (59-61)
tests/transports-integrations/tests/integrations/test_anthropic.py (2)
  • test_12_error_handling_invalid_roles (552-564)
  • test_config (88-90)
tests/transports-integrations/tests/utils/config_loader.py (2)
  • get_model (128-140)
  • get_model (280-282)
tests/transports-integrations/tests/integrations/test_anthropic.py (5)
tests/transports-integrations/tests/utils/common.py (2)
  • assert_valid_error_response (464-547)
  • assert_error_propagation (550-635)
tests/transports-integrations/tests/integrations/test_google.py (2)
  • test_12_error_handling_invalid_roles (430-440)
  • test_config (75-77)
tests/transports-integrations/tests/integrations/test_litellm.py (2)
  • test_12_error_handling_invalid_roles (347-359)
  • test_config (59-61)
tests/transports-integrations/tests/integrations/test_openai.py (2)
  • test_12_error_handling_invalid_roles (397-409)
  • test_config (130-132)
tests/transports-integrations/tests/utils/config_loader.py (2)
  • get_model (128-140)
  • get_model (280-282)
transports/bifrost-http/integrations/openai/router.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ErrorConverter (32-32)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
transports/bifrost-http/integrations/openai/types.go (1)
  • DeriveOpenAIErrorFromBifrostError (157-199)
transports/bifrost-http/integrations/litellm/router.go (5)
core/schemas/bifrost.go (5)
  • BifrostError (433-441)
  • OpenAI (40-40)
  • Azure (41-41)
  • Anthropic (42-42)
  • Vertex (45-45)
transports/bifrost-http/integrations/openai/types.go (1)
  • DeriveOpenAIErrorFromBifrostError (157-199)
transports/bifrost-http/integrations/anthropic/types.go (1)
  • DeriveAnthropicErrorFromBifrostError (481-506)
transports/bifrost-http/integrations/genai/types.go (1)
  • DeriveGeminiErrorFromBifrostError (583-606)
transports/bifrost-http/integrations/utils.go (1)
  • ErrorConverter (32-32)
tests/transports-integrations/tests/integrations/test_google.py (5)
tests/transports-integrations/tests/utils/common.py (4)
  • assert_valid_error_response (464-547)
  • assert_error_propagation (550-635)
  • get_api_key (657-674)
  • skip_if_no_api_key (677-688)
tests/transports-integrations/tests/integrations/test_litellm.py (2)
  • test_12_error_handling_invalid_roles (347-359)
  • test_config (59-61)
tests/transports-integrations/tests/integrations/test_anthropic.py (2)
  • test_12_error_handling_invalid_roles (552-564)
  • test_config (88-90)
tests/transports-integrations/tests/integrations/test_openai.py (2)
  • test_12_error_handling_invalid_roles (397-409)
  • test_config (130-132)
tests/transports-integrations/tests/utils/config_loader.py (2)
  • get_model (128-140)
  • get_model (280-282)
core/bifrost.go (2)
core/schemas/provider.go (1)
  • Provider (154-163)
core/schemas/bifrost.go (1)
  • RequestCancelled (424-424)
transports/bifrost-http/integrations/anthropic/types.go (1)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
transports/bifrost-http/integrations/genai/types.go (1)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
transports/bifrost-http/integrations/utils.go (2)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
transports/bifrost-http/lib/ctx.go (1)
  • ConvertToBifrostContext (54-100)
transports/bifrost-http/integrations/openai/types.go (1)
core/schemas/bifrost.go (1)
  • BifrostError (433-441)
🪛 LanguageTool
tests/transports-integrations/README.md

[grammar] ~37-~37: Use correct spacing
Context: ...ers 12 comprehensive scenarios for each integration: 1. Simple Chat - Basic single-message co...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🪛 Ruff (0.11.9)
tests/transports-integrations/tests/integrations/test_openai.py

397-397: Missing return type annotation for public function test_12_error_handling_invalid_roles

Add return type annotation: None

(ANN201)


397-397: Missing type annotation for function argument openai_client

(ANN001)


397-397: Missing type annotation for function argument test_config

(ANN001)


397-397: Unused method argument: test_config

(ARG002)


399-399: pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception

(PT011)

tests/transports-integrations/tests/integrations/test_anthropic.py

41-41: ..utils.common.ALL_TOOLS imported but unused

Remove unused import: ..utils.common.ALL_TOOLS

(F401)


552-552: Missing return type annotation for public function test_12_error_handling_invalid_roles

Add return type annotation: None

(ANN201)


552-552: Missing type annotation for function argument anthropic_client

(ANN001)


552-552: Missing type annotation for function argument test_config

(ANN001)


552-552: Unused method argument: test_config

(ARG002)


554-554: pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception

(PT011)

tests/transports-integrations/tests/integrations/test_litellm.py

49-49: ..utils.common.get_api_key imported but unused

Remove unused import

(F401)


50-50: ..utils.common.skip_if_no_api_key imported but unused

Remove unused import

(F401)


347-347: Missing return type annotation for public function test_12_error_handling_invalid_roles

Add return type annotation: None

(ANN201)


347-347: Missing type annotation for function argument test_config

(ANN001)


347-347: Unused method argument: test_config

(ARG002)


349-349: pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception

(PT011)

tests/transports-integrations/tests/integrations/test_google.py

34-34: ..utils.common.INVALID_ROLE_MESSAGES imported but unused

Remove unused import: ..utils.common.INVALID_ROLE_MESSAGES

(F401)


430-430: Missing return type annotation for public function test_12_error_handling_invalid_roles

Add return type annotation: None

(ANN201)


430-430: Missing type annotation for function argument google_client

(ANN001)


430-430: Missing type annotation for function argument test_config

(ANN001)


430-430: Unused method argument: test_config

(ARG002)


432-432: pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception

(PT011)


434-434: Trailing comma missing

Add trailing comma

(COM812)

tests/transports-integrations/tests/utils/common.py

195-195: Trailing comma missing

Add trailing comma

(COM812)


203-203: Trailing comma missing

Add trailing comma

(COM812)


205-205: Trailing comma missing

Add trailing comma

(COM812)


464-464: Missing return type annotation for public function assert_valid_error_response

Add return type annotation: bool

(ANN201)


465-465: Dynamically typed expressions (typing.Any) are disallowed in response_or_exception

(ANN401)


465-465: Trailing comma missing

Add trailing comma

(COM812)


490-490: Trailing comma missing

Add trailing comma

(COM812)


499-499: Do not use bare except

(E722)


550-550: Missing return type annotation for public function assert_error_propagation

Add return type annotation: bool

(ANN201)


550-550: Dynamically typed expressions (typing.Any) are disallowed in error_response

(ANN401)


574-574: Trailing comma missing

Add trailing comma

(COM812)


577-577: Trailing comma missing

Add trailing comma

(COM812)


598-598: Trailing comma missing

Add trailing comma

(COM812)


608-610: Use a single if statement instead of nested if statements

(SIM102)


620-620: Trailing comma missing

Add trailing comma

(COM812)


626-626: Trailing comma missing

Add trailing comma

(COM812)


632-632: Trailing comma missing

Add trailing comma

(COM812)

🔇 Additional comments (28)
core/schemas/bifrost.go (1)

434-434: LGTM! Well-designed provider tracking for error handling.

The addition of the Provider field enables accurate error attribution and supports the provider-specific error conversion implemented in the router layers. The json:"-" tag appropriately excludes this internal metadata from client responses.

tests/transports-integrations/README.md (3)

37-37: LGTM! Documentation accurately reflects the enhanced test coverage.

The update from 11 to 12 test categories correctly incorporates the new error handling tests.


50-50: LGTM! Clear description of the new error handling test category.

The addition properly describes the scope and purpose of the error handling tests.


184-186: LGTM! Helpful examples for running error handling tests.

The pytest examples provide clear guidance for running the new error handling test category specifically.

transports/bifrost-http/integrations/openai/router.go (1)

35-37: LGTM! Proper integration of provider-specific error conversion.

The ErrorConverter implementation correctly transforms BifrostError instances into OpenAI-specific error formats, enabling accurate error responses for OpenAI integration clients.

transports/bifrost-http/integrations/genai/router.go (1)

37-39: LGTM! Consistent error conversion implementation for Google GenAI.

The ErrorConverter properly transforms BifrostError instances into Gemini-specific error formats, maintaining consistency with the error handling pattern across all integrations.

transports/bifrost-http/integrations/anthropic/router.go (1)

35-37: LGTM! Proper Anthropic-specific error conversion implementation.

The ErrorConverter correctly transforms BifrostError instances into Anthropic-specific error formats, completing the consistent error handling enhancement across all supported integrations.

tests/transports-integrations/tests/integrations/test_google.py (1)

429-441: LGTM! Consistent error handling test implementation.

The test correctly validates error handling for invalid roles using Google GenAI's specific content format and follows the established pattern used across other integrations.

tests/transports-integrations/tests/integrations/test_openai.py (1)

396-409: LGTM! Consistent error handling test across integrations.

The test correctly validates error handling for invalid roles and follows the established pattern. The error response validation and propagation checks ensure proper error handling through the Bifrost transport layer.

tests/transports-integrations/tests/integrations/test_litellm.py (1)

347-359: LGTM! Consistent error handling test implementation.

The test correctly validates error handling for invalid roles and follows the established pattern across all integrations. The error validation ensures proper propagation through the Bifrost transport layer.

core/bifrost.go (3)

195-196: LGTM: Provider field assignment in TextCompletionRequest.

The error provider assignment is correctly implemented for all error paths:

  • Validation errors use req.Provider
  • Cancelled request errors use req.Provider
  • Short-circuit errors use req.Provider
  • Fallback cancellation errors use fallback.Provider
  • Final primary errors use req.Provider

This ensures proper error provenance tracking.

Also applies to: 206-207, 213-214, 240-241, 248-249


259-260: LGTM: Provider field assignment in ChatCompletionRequest.

The error provider assignment follows the same correct pattern as TextCompletionRequest:

  • All primary provider errors are assigned req.Provider
  • Fallback provider errors are assigned fallback.Provider
  • Cancelled requests are properly handled with appropriate provider assignment

The implementation is consistent and complete.

Also applies to: 269-272, 277-278, 304-305, 312-313


323-324: LGTM: Provider field assignment in EmbeddingRequest.

The error provider assignment maintains consistency with the other request methods:

  • Validation errors correctly use req.Provider
  • Cancelled request handling is properly implemented
  • Short-circuit and fallback error handling follows the established pattern

All error paths now include provider information for proper error tracking.

Also applies to: 337-340, 345-346, 371-372, 379-380

transports/bifrost-http/integrations/litellm/router.go (2)

143-154: LGTM: Provider-specific error converter implementation.

The error converter correctly:

  • Switches on the err.Provider field to determine the appropriate conversion
  • Calls the correct provider-specific error conversion functions for OpenAI/Azure, Anthropic, and Vertex
  • Falls back to returning the original error for unknown providers
  • Handles nil errors appropriately (the called functions have nil checks)

This implementation aligns with the broader error handling improvements across all integrations.


164-164: LGTM: Error converter integration in route configuration.

The ErrorConverter field assignment correctly integrates the new error conversion functionality into the routing configuration, ensuring that all error responses from LiteLLM routes will be properly formatted according to the originating provider's error format.

transports/bifrost-http/integrations/genai/types.go (2)

139-149: LGTM: Well-structured error types following Google API format.

The error type definitions correctly model the Gemini/Google GenAI error response structure with appropriate JSON tags and field types.


582-606: LGTM: Robust error converter with proper nil handling.

The error converter function demonstrates excellent defensive programming:

  • Handles nil input gracefully
  • Provides sensible defaults (HTTP 500, empty status)
  • Safely dereferences all pointer fields with nil checks
  • Follows consistent patterns with other integration converters

This implementation aligns well with the team's preference for consistent error handling patterns.

transports/bifrost-http/integrations/anthropic/types.go (2)

96-106: LGTM: Clean error type definitions matching Anthropic API structure.

The error types correctly model Anthropic's messages API error response format with appropriate JSON tags and field organization.


480-506: LGTM: Safe and consistent error converter implementation.

The error converter function demonstrates solid defensive programming practices:

  • Proper nil input handling
  • Safe pointer dereferencing with nil checks for both top-level and nested error fields
  • Consistent initialization with empty strings for missing values
  • Follows the same reliable pattern established across all integration converters

This implementation maintains the consistent error handling patterns preferred by the team.

transports/bifrost-http/integrations/openai/types.go (2)

42-62: LGTM: Comprehensive error types matching OpenAI API structure.

The error type definitions correctly model OpenAI's chat completion error response format with:

  • Proper JSON tags for all fields
  • Comprehensive error fields including event tracking
  • Clean structure using both named and anonymous structs

156-199: LGTM: Thorough error converter with comprehensive field mapping.

The error converter function demonstrates excellent implementation quality:

  • Proper nil input validation
  • Safe dereferencing of all pointer fields (EventID, Type, nested Error fields)
  • Comprehensive mapping of all error fields from BifrostError to OpenAI format
  • Consistent error handling patterns with empty string defaults
  • Follows the established pattern across all integration converters

This implementation aligns perfectly with the team's consistent error handling approach.

transports/bifrost-http/integrations/utils.go (6)

30-32: LGTM: Clean abstraction for error conversion.

The ErrorConverter type provides a clean, simple interface for converting BifrostError instances to integration-specific error formats.


52-52: LGTM: Consistent integration of ErrorConverter into route configuration.

Adding ErrorConverter as a required field to RouteConfig ensures all routes have provider-specific error handling capabilities.


91-94: LGTM: Proper validation following established patterns.

The validation check for ErrorConverter being non-nil follows the same pattern as other required route configuration fields, ensuring fail-fast behavior during startup.


139-139: LGTM: Comprehensive and consistent error handling updates.

All error handling calls have been systematically updated to include the ErrorConverter parameter, ensuring consistent provider-specific error formatting throughout the request handling flow.

Also applies to: 150-150, 158-158, 162-162, 166-166, 174-174, 181-181, 187-187, 194-194, 197-197


203-219: LGTM: Well-designed centralized error response handling.

The updated sendError method effectively centralizes error conversion and response formatting:

  • Uses the provided ErrorConverter to format errors appropriately for each integration
  • Maintains proper HTTP status code handling from BifrostError.StatusCode
  • Includes appropriate fallback error handling for JSON marshaling failures
  • Clean separation of concerns between error conversion and HTTP response generation

222-222: LGTM: Consistent error converter integration in success path.

The sendSuccess method properly passes the ErrorConverter to sendError for consistent error handling even in the success path when JSON marshaling fails.

Also applies to: 228-228

tests/transports-integrations/tests/utils/common.py (1)

653-653: Good addition for error handling test categorization.

The new ERROR_HANDLING test category aligns well with the PR objectives of adding comprehensive error handling tests across integrations.

MULTIPLE_TOOL_CALL_MESSAGES,
IMAGE_URL,
BASE64_IMAGE,
INVALID_ROLE_MESSAGES,
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.

🧹 Nitpick (assertive)

Remove unused import.

The INVALID_ROLE_MESSAGES import is not used in this test file since Google GenAI uses GENAI_INVALID_ROLE_CONTENT instead.

-    INVALID_ROLE_MESSAGES,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
INVALID_ROLE_MESSAGES,
from ..utils.common import (
GENAI_INVALID_ROLE_CONTENT,
)
🧰 Tools
🪛 Ruff (0.11.9)

34-34: ..utils.common.INVALID_ROLE_MESSAGES imported but unused

Remove unused import: ..utils.common.INVALID_ROLE_MESSAGES

(F401)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/integrations/test_google.py at line 34,
remove the import of INVALID_ROLE_MESSAGES since it is not used in this file;
the tests use GENAI_INVALID_ROLE_CONTENT instead. Simply delete the line
importing INVALID_ROLE_MESSAGES to clean up unused imports.

Comment on lines +49 to +50
get_api_key,
skip_if_no_api_key,
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.

🧹 Nitpick (assertive)

Remove unused imports.

The get_api_key and skip_if_no_api_key imports are not used in this test file. Based on the established pattern for LiteLLM tests, these should be removed.

-    get_api_key,
-    skip_if_no_api_key,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
get_api_key,
skip_if_no_api_key,
- get_api_key,
- skip_if_no_api_key,
🧰 Tools
🪛 Ruff (0.11.9)

49-49: ..utils.common.get_api_key imported but unused

Remove unused import

(F401)


50-50: ..utils.common.skip_if_no_api_key imported but unused

Remove unused import

(F401)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/integrations/test_litellm.py around lines
49 to 50, the imports get_api_key and skip_if_no_api_key are not used anywhere
in the file. Remove these two imports to clean up the code and follow the
established pattern for LiteLLM tests.

Comment on lines +38 to +41
INVALID_ROLE_MESSAGES,
WEATHER_TOOL,
CALCULATOR_TOOL,
ALL_TOOLS,
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.

🧹 Nitpick (assertive)

Remove unused import.

The ALL_TOOLS import is not used in this test file.

-    ALL_TOOLS,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
INVALID_ROLE_MESSAGES,
WEATHER_TOOL,
CALCULATOR_TOOL,
ALL_TOOLS,
INVALID_ROLE_MESSAGES,
WEATHER_TOOL,
CALCULATOR_TOOL,
🧰 Tools
🪛 Ruff (0.11.9)

41-41: ..utils.common.ALL_TOOLS imported but unused

Remove unused import: ..utils.common.ALL_TOOLS

(F401)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/integrations/test_anthropic.py around
lines 38 to 41, the import ALL_TOOLS is not used anywhere in the file. Remove
the ALL_TOOLS import from the import statement to clean up unused code.

Comment on lines +551 to +565
@skip_if_no_api_key("anthropic")
def test_12_error_handling_invalid_roles(self, anthropic_client, test_config):
"""Test Case 12: Error handling for invalid roles"""
with pytest.raises(Exception) as exc_info:
anthropic_client.messages.create(
model=get_model("anthropic", "chat"),
messages=INVALID_ROLE_MESSAGES,
max_tokens=100,
)

# Verify the error is properly caught and contains role-related information
error = exc_info.value
assert_valid_error_response(error, "tester")
assert_error_propagation(error, "anthropic")

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.

🧹 Nitpick (assertive)

Improve error handling test specificity.

The test implementation follows the correct pattern but could be improved:

  1. The exception type is too broad - consider using a more specific exception type
  2. Add proper type annotations for better code quality
-    def test_12_error_handling_invalid_roles(self, anthropic_client, test_config):
+    def test_12_error_handling_invalid_roles(self, anthropic_client, test_config) -> None:
         """Test Case 12: Error handling for invalid roles"""
-        with pytest.raises(Exception) as exc_info:
+        with pytest.raises(Exception, match=r".*(role|invalid|tester).*") as exc_info:

The test correctly validates error propagation and follows the established pattern across other integration tests.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@skip_if_no_api_key("anthropic")
def test_12_error_handling_invalid_roles(self, anthropic_client, test_config):
"""Test Case 12: Error handling for invalid roles"""
with pytest.raises(Exception) as exc_info:
anthropic_client.messages.create(
model=get_model("anthropic", "chat"),
messages=INVALID_ROLE_MESSAGES,
max_tokens=100,
)
# Verify the error is properly caught and contains role-related information
error = exc_info.value
assert_valid_error_response(error, "tester")
assert_error_propagation(error, "anthropic")
@skip_if_no_api_key("anthropic")
def test_12_error_handling_invalid_roles(self, anthropic_client, test_config) -> None:
"""Test Case 12: Error handling for invalid roles"""
with pytest.raises(Exception, match=r".*(role|invalid|tester).*") as exc_info:
anthropic_client.messages.create(
model=get_model("anthropic", "chat"),
messages=INVALID_ROLE_MESSAGES,
max_tokens=100,
)
# Verify the error is properly caught and contains role-related information
error = exc_info.value
assert_valid_error_response(error, "tester")
assert_error_propagation(error, "anthropic")
🧰 Tools
🪛 Ruff (0.11.9)

552-552: Missing return type annotation for public function test_12_error_handling_invalid_roles

Add return type annotation: None

(ANN201)


552-552: Missing type annotation for function argument anthropic_client

(ANN001)


552-552: Missing type annotation for function argument test_config

(ANN001)


552-552: Unused method argument: test_config

(ARG002)


554-554: pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception

(PT011)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/integrations/test_anthropic.py around
lines 551 to 565, the test_12_error_handling_invalid_roles function uses a broad
Exception type in pytest.raises and lacks type annotations. Update the test to
catch a more specific exception type relevant to invalid roles, such as a custom
error or a more precise built-in exception. Additionally, add appropriate type
annotations to the test method parameters and return type to improve code
clarity and quality.

Comment on lines +464 to +547
def assert_valid_error_response(
response_or_exception: Any, expected_invalid_role: str = "tester"
):
"""
Assert that an error response or exception properly indicates an invalid role error.

WEATHER_KEYWORDS = [
"weather",
"temperature",
"sunny",
"cloudy",
"rain",
"snow",
"celsius",
"fahrenheit",
"degrees",
"hot",
"cold",
"warm",
"cool",
]
Args:
response_or_exception: Either an HTTP error response or a raised exception
expected_invalid_role: The invalid role that should be mentioned in the error
"""
error_message = ""
error_type = ""
status_code = None

LOCATION_KEYWORDS = ["boston", "san francisco", "new york", "city", "location", "place"]
# Handle different error response formats
if hasattr(response_or_exception, "response"):
# This is likely a requests.HTTPError or similar
try:
error_data = response_or_exception.response.json()
status_code = response_or_exception.response.status_code

# Extract error message from various formats
if isinstance(error_data, dict):
if "error" in error_data:
if isinstance(error_data["error"], dict):
error_message = error_data["error"].get(
"message", str(error_data["error"])
)
error_type = error_data["error"].get("type", "")
else:
error_message = str(error_data["error"])
else:
error_message = error_data.get("message", str(error_data))
else:
error_message = str(error_data)
except:
error_message = str(response_or_exception)

elif hasattr(response_or_exception, "message"):
# Direct error object
error_message = response_or_exception.message

elif hasattr(response_or_exception, "args") and response_or_exception.args:
# Exception with args
error_message = str(response_or_exception.args[0])

else:
# Fallback to string representation
error_message = str(response_or_exception)

# Convert to lowercase for case-insensitive matching
error_message_lower = error_message.lower()
error_type_lower = error_type.lower()

# Validate that error message indicates role-related issue
role_error_indicators = [
expected_invalid_role.lower(),
"role",
"invalid",
"unsupported",
"unknown",
"not allowed",
"not supported",
"bad request",
"invalid_request",
]

has_role_error = any(
indicator in error_message_lower or indicator in error_type_lower
for indicator in role_error_indicators
)

assert has_role_error, (
f"Error message should indicate invalid role '{expected_invalid_role}'. "
f"Got error message: '{error_message}', error type: '{error_type}'"
)

# Validate status code if available (should be 4xx for client errors)
if status_code is not None:
assert (
400 <= status_code < 500
), f"Expected 4xx status code for invalid role error, got {status_code}"

return True
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.

🛠️ Refactor suggestion

Improve error handling and add type annotations.

The function logic is solid for validating error responses across different formats. Address these style and safety issues:

Apply this diff to improve the function:

-def assert_valid_error_response(
-    response_or_exception: Any, expected_invalid_role: str = "tester"
-):
+def assert_valid_error_response(
+    response_or_exception: Any, expected_invalid_role: str = "tester",
+) -> bool:
-                        error_message = error_data["error"].get(
-                            "message", str(error_data["error"])
-                        )
+                        error_message = error_data["error"].get(
+                            "message", str(error_data["error"])
+                        ),
-        except:
+        except (ValueError, KeyError, AttributeError):
             error_message = str(response_or_exception)

The bare except clause should be replaced with specific exception types to avoid masking unexpected errors during development and debugging.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.11.9)

464-464: Missing return type annotation for public function assert_valid_error_response

Add return type annotation: bool

(ANN201)


465-465: Dynamically typed expressions (typing.Any) are disallowed in response_or_exception

(ANN401)


465-465: Trailing comma missing

Add trailing comma

(COM812)


490-490: Trailing comma missing

Add trailing comma

(COM812)


499-499: Do not use bare except

(E722)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/utils/common.py around lines 464 to 547,
the function assert_valid_error_response uses a bare except clause which can
mask unexpected errors. Replace the bare except with specific exceptions such as
JSONDecodeError and AttributeError when attempting to parse the JSON response to
improve error handling and avoid hiding bugs. Additionally, add appropriate type
annotations to the function signature and variables to enhance code clarity and
safety.

Comment on lines +154 to +221
# Common keyword arrays for flexible assertions
COMPARISON_KEYWORDS = [
"compare",
"comparison",
"different",
"difference",
"differences",
"both",
"two",
"first",
"second",
"images",
"image",
"versus",
"vs",
"contrast",
"unlike",
"while",
"whereas",
]

WEATHER_KEYWORDS = [
"weather",
"temperature",
"sunny",
"cloudy",
"rain",
"snow",
"celsius",
"fahrenheit",
"degrees",
"hot",
"cold",
"warm",
"cool",
]

LOCATION_KEYWORDS = ["boston", "san francisco", "new york", "city", "location", "place"]

# Error test data for invalid role testing
INVALID_ROLE_MESSAGES = [
{"role": "tester", "content": "Hello! This should fail due to invalid role."}
]

# GenAI-specific invalid role content that passes SDK validation but fails at Bifrost
GENAI_INVALID_ROLE_CONTENT = [
{
"role": "tester", # Invalid role that should be caught by Bifrost
"parts": [
{"text": "Hello! This should fail due to invalid role in GenAI format."}
],
}
]

# Error keywords for validating error messages
ERROR_KEYWORDS = [
"invalid",
"error",
"role",
"tester",
"unsupported",
"unknown",
"bad",
"incorrect",
"not allowed",
"not supported",
"forbidden",
]
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.

🧹 Nitpick (assertive)

Add trailing commas for consistency.

The keyword arrays and test data look comprehensive and well-organized. Consider adding trailing commas to list elements for consistency with Python style guidelines.

Apply this diff to add missing trailing commas:

-    {"role": "tester", "content": "Hello! This should fail due to invalid role."}
+    {"role": "tester", "content": "Hello! This should fail due to invalid role."},
-        "role": "tester",  # Invalid role that should be caught by Bifrost
+        "role": "tester",  # Invalid role that should be caught by Bifrost
         "parts": [
             {"text": "Hello! This should fail due to invalid role in GenAI format."}
-        ],
+        ],
-            {"text": "Hello! This should fail due to invalid role in GenAI format."}
+            {"text": "Hello! This should fail due to invalid role in GenAI format."},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Common keyword arrays for flexible assertions
COMPARISON_KEYWORDS = [
"compare",
"comparison",
"different",
"difference",
"differences",
"both",
"two",
"first",
"second",
"images",
"image",
"versus",
"vs",
"contrast",
"unlike",
"while",
"whereas",
]
WEATHER_KEYWORDS = [
"weather",
"temperature",
"sunny",
"cloudy",
"rain",
"snow",
"celsius",
"fahrenheit",
"degrees",
"hot",
"cold",
"warm",
"cool",
]
LOCATION_KEYWORDS = ["boston", "san francisco", "new york", "city", "location", "place"]
# Error test data for invalid role testing
INVALID_ROLE_MESSAGES = [
{"role": "tester", "content": "Hello! This should fail due to invalid role."}
]
# GenAI-specific invalid role content that passes SDK validation but fails at Bifrost
GENAI_INVALID_ROLE_CONTENT = [
{
"role": "tester", # Invalid role that should be caught by Bifrost
"parts": [
{"text": "Hello! This should fail due to invalid role in GenAI format."}
],
}
]
# Error keywords for validating error messages
ERROR_KEYWORDS = [
"invalid",
"error",
"role",
"tester",
"unsupported",
"unknown",
"bad",
"incorrect",
"not allowed",
"not supported",
"forbidden",
]
# Error test data for invalid role testing
INVALID_ROLE_MESSAGES = [
{"role": "tester", "content": "Hello! This should fail due to invalid role."},
]
# GenAI-specific invalid role content that passes SDK validation but fails at Bifrost
GENAI_INVALID_ROLE_CONTENT = [
{
"role": "tester", # Invalid role that should be caught by Bifrost
"parts": [
{"text": "Hello! This should fail due to invalid role in GenAI format."},
],
},
]
🧰 Tools
🪛 Ruff (0.11.9)

195-195: Trailing comma missing

Add trailing comma

(COM812)


203-203: Trailing comma missing

Add trailing comma

(COM812)


205-205: Trailing comma missing

Add trailing comma

(COM812)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/utils/common.py between lines 154 and
221, the lists defining keyword arrays and test data lack trailing commas on the
last elements. To fix this, add trailing commas after the last item in each list
and dictionary to maintain consistency with Python style guidelines and improve
diff clarity.

Comment on lines +550 to +635
def assert_error_propagation(error_response: Any, integration: str):
"""
Assert that error is properly propagated through Bifrost to the integration.

Args:
error_response: The error response from the integration
integration: The integration name (openai, anthropic, etc.)
"""
# Check that we got an error response (not a success)
assert error_response is not None, "Should have received an error response"

# Integration-specific error format validation
if integration.lower() == "openai":
# OpenAI format: should have top-level 'type', 'event_id' and 'error' field with nested structure
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "OpenAI error should have 'error' field"
assert (
"type" in error_data
), "OpenAI error should have top-level 'type' field"
assert (
"event_id" in error_data
), "OpenAI error should have top-level 'event_id' field"
assert isinstance(
error_data["type"], str
), "OpenAI error type should be a string"
assert isinstance(
error_data["event_id"], str
), "OpenAI error event_id should be a string"

# Check nested error structure
error_obj = error_data["error"]
assert (
"message" in error_obj
), "OpenAI error.error should have 'message' field"
assert "type" in error_obj, "OpenAI error.error should have 'type' field"
assert "code" in error_obj, "OpenAI error.error should have 'code' field"
assert (
"event_id" in error_obj
), "OpenAI error.error should have 'event_id' field"

elif integration.lower() == "anthropic":
# Anthropic format: should have 'type' and 'error' with 'type' and 'message'
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "type" in error_data, "Anthropic error should have 'type' field"
# Type field can be empty string if not set in original error
assert isinstance(
error_data["type"], str
), "Anthropic error type should be a string"
assert "error" in error_data, "Anthropic error should have 'error' field"
assert (
"type" in error_data["error"]
), "Anthropic error.error should have 'type' field"
assert (
"message" in error_data["error"]
), "Anthropic error.error should have 'message' field"

elif integration.lower() in ["google", "gemini", "genai"]:
# Gemini format: follows Google API design guidelines with error.code, error.message, error.status
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "Gemini error should have 'error' field"

# Check Google API standard error structure
error_obj = error_data["error"]
assert (
"code" in error_obj
), "Gemini error.error should have 'code' field (HTTP status code)"
assert isinstance(
error_obj["code"], int
), "Gemini error.error.code should be an integer"
assert (
"message" in error_obj
), "Gemini error.error should have 'message' field"
assert isinstance(
error_obj["message"], str
), "Gemini error.error.message should be a string"
assert (
"status" in error_obj
), "Gemini error.error should have 'status' field"
assert isinstance(
error_obj["status"], str
), "Gemini error.error.status should be a string"

return True
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.

🧹 Nitpick (assertive)

Add type annotation and fix style issues - excellent error validation logic.

The error propagation validation is comprehensive and correctly validates integration-specific error formats. The logic properly ensures errors are formatted according to each provider's API conventions.

Apply this diff to address style issues:

-def assert_error_propagation(error_response: Any, integration: str):
+def assert_error_propagation(error_response: Any, integration: str) -> bool:
-            assert isinstance(
-                error_data["type"], str
-            ), "OpenAI error type should be a string"
+            assert isinstance(
+                error_data["type"], str,
+            ), "OpenAI error type should be a string"
-            assert isinstance(
-                error_data["event_id"], str
-            ), "OpenAI error event_id should be a string"
+            assert isinstance(
+                error_data["event_id"], str,
+            ), "OpenAI error event_id should be a string"
-            assert isinstance(
-                error_data["type"], str
-            ), "Anthropic error type should be a string"
+            assert isinstance(
+                error_data["type"], str,
+            ), "Anthropic error type should be a string"
-            assert isinstance(
-                error_obj["code"], int
-            ), "Gemini error.error.code should be an integer"
+            assert isinstance(
+                error_obj["code"], int,
+            ), "Gemini error.error.code should be an integer"
-            assert isinstance(
-                error_obj["message"], str
-            ), "Gemini error.error.message should be a string"
+            assert isinstance(
+                error_obj["message"], str,
+            ), "Gemini error.error.message should be a string"
-            assert isinstance(
-                error_obj["status"], str
-            ), "Gemini error.error.status should be a string"
+            assert isinstance(
+                error_obj["status"], str,
+            ), "Gemini error.error.status should be a string"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def assert_error_propagation(error_response: Any, integration: str):
"""
Assert that error is properly propagated through Bifrost to the integration.
Args:
error_response: The error response from the integration
integration: The integration name (openai, anthropic, etc.)
"""
# Check that we got an error response (not a success)
assert error_response is not None, "Should have received an error response"
# Integration-specific error format validation
if integration.lower() == "openai":
# OpenAI format: should have top-level 'type', 'event_id' and 'error' field with nested structure
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "OpenAI error should have 'error' field"
assert (
"type" in error_data
), "OpenAI error should have top-level 'type' field"
assert (
"event_id" in error_data
), "OpenAI error should have top-level 'event_id' field"
assert isinstance(
error_data["type"], str
), "OpenAI error type should be a string"
assert isinstance(
error_data["event_id"], str
), "OpenAI error event_id should be a string"
# Check nested error structure
error_obj = error_data["error"]
assert (
"message" in error_obj
), "OpenAI error.error should have 'message' field"
assert "type" in error_obj, "OpenAI error.error should have 'type' field"
assert "code" in error_obj, "OpenAI error.error should have 'code' field"
assert (
"event_id" in error_obj
), "OpenAI error.error should have 'event_id' field"
elif integration.lower() == "anthropic":
# Anthropic format: should have 'type' and 'error' with 'type' and 'message'
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "type" in error_data, "Anthropic error should have 'type' field"
# Type field can be empty string if not set in original error
assert isinstance(
error_data["type"], str
), "Anthropic error type should be a string"
assert "error" in error_data, "Anthropic error should have 'error' field"
assert (
"type" in error_data["error"]
), "Anthropic error.error should have 'type' field"
assert (
"message" in error_data["error"]
), "Anthropic error.error should have 'message' field"
elif integration.lower() in ["google", "gemini", "genai"]:
# Gemini format: follows Google API design guidelines with error.code, error.message, error.status
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "Gemini error should have 'error' field"
# Check Google API standard error structure
error_obj = error_data["error"]
assert (
"code" in error_obj
), "Gemini error.error should have 'code' field (HTTP status code)"
assert isinstance(
error_obj["code"], int
), "Gemini error.error.code should be an integer"
assert (
"message" in error_obj
), "Gemini error.error should have 'message' field"
assert isinstance(
error_obj["message"], str
), "Gemini error.error.message should be a string"
assert (
"status" in error_obj
), "Gemini error.error should have 'status' field"
assert isinstance(
error_obj["status"], str
), "Gemini error.error.status should be a string"
return True
def assert_error_propagation(error_response: Any, integration: str) -> bool:
"""
Assert that error is properly propagated through Bifrost to the integration.
Args:
error_response: The error response from the integration
integration: The integration name (openai, anthropic, etc.)
"""
# Check that we got an error response (not a success)
assert error_response is not None, "Should have received an error response"
# Integration-specific error format validation
if integration.lower() == "openai":
# OpenAI format: should have top-level 'type', 'event_id' and 'error' field with nested structure
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "OpenAI error should have 'error' field"
assert (
"type" in error_data
), "OpenAI error should have top-level 'type' field"
assert (
"event_id" in error_data
), "OpenAI error should have top-level 'event_id' field"
assert isinstance(
error_data["type"], str,
), "OpenAI error type should be a string"
assert isinstance(
error_data["event_id"], str,
), "OpenAI error event_id should be a string"
# Check nested error structure
error_obj = error_data["error"]
assert (
"message" in error_obj
), "OpenAI error.error should have 'message' field"
assert "type" in error_obj, "OpenAI error.error should have 'type' field"
assert "code" in error_obj, "OpenAI error.error should have 'code' field"
assert (
"event_id" in error_obj
), "OpenAI error.error should have 'event_id' field"
elif integration.lower() == "anthropic":
# Anthropic format: should have 'type' and 'error' with 'type' and 'message'
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "type" in error_data, "Anthropic error should have 'type' field"
# Type field can be empty string if not set in original error
assert isinstance(
error_data["type"], str,
), "Anthropic error type should be a string"
assert "error" in error_data, "Anthropic error should have 'error' field"
assert (
"type" in error_data["error"]
), "Anthropic error.error should have 'type' field"
assert (
"message" in error_data["error"]
), "Anthropic error.error should have 'message' field"
elif integration.lower() in ["google", "gemini", "genai"]:
# Gemini format: follows Google API design guidelines with error.code, error.message, error.status
if hasattr(error_response, "response"):
error_data = error_response.response.json()
assert "error" in error_data, "Gemini error should have 'error' field"
# Check Google API standard error structure
error_obj = error_data["error"]
assert (
"code" in error_obj
), "Gemini error.error should have 'code' field (HTTP status code)"
assert isinstance(
error_obj["code"], int,
), "Gemini error.error.code should be an integer"
assert (
"message" in error_obj
), "Gemini error.error should have 'message' field"
assert isinstance(
error_obj["message"], str,
), "Gemini error.error.message should be a string"
assert (
"status" in error_obj
), "Gemini error.error should have 'status' field"
assert isinstance(
error_obj["status"], str,
), "Gemini error.error.status should be a string"
return True
🧰 Tools
🪛 Ruff (0.11.9)

550-550: Missing return type annotation for public function assert_error_propagation

Add return type annotation: bool

(ANN201)


550-550: Dynamically typed expressions (typing.Any) are disallowed in error_response

(ANN401)


574-574: Trailing comma missing

Add trailing comma

(COM812)


577-577: Trailing comma missing

Add trailing comma

(COM812)


598-598: Trailing comma missing

Add trailing comma

(COM812)


608-610: Use a single if statement instead of nested if statements

(SIM102)


620-620: Trailing comma missing

Add trailing comma

(COM812)


626-626: Trailing comma missing

Add trailing comma

(COM812)


632-632: Trailing comma missing

Add trailing comma

(COM812)

🤖 Prompt for AI Agents
In tests/transports-integrations/tests/utils/common.py around lines 550 to 635,
add precise type annotations to the function parameters and return type for
better clarity and type checking. Also, fix any style issues such as consistent
indentation, line length, and spacing to comply with PEP8 standards while
preserving the existing error validation logic.

@akshaydeo akshaydeo merged commit 97abd14 into main Jul 10, 2025
2 checks passed
@akshaydeo akshaydeo deleted the 07-10-feat_error_handling_added_for_transport_integrations_with_their_test_cases branch August 31, 2025 17:28
akshaydeo added a commit that referenced this pull request Nov 17, 2025
# Add Provider Information to BifrostError for Improved Error Propagation

This PR enhances error handling in Bifrost by adding provider information to `BifrostError` objects and ensuring proper error propagation through the system. The changes enable more accurate error reporting when requests fail, making it easier to identify which provider encountered an issue.

Key improvements:

- Added a `Provider` field to the `BifrostError` struct to track which provider generated the error
- Set the provider field at all error creation points in the request flow
- Implemented provider-specific error converters for each integration (OpenAI, Anthropic, Google, LiteLLM)
- Added proper error propagation in the HTTP transport layer
- Enhanced error handling for cancelled requests
- Added comprehensive error handling tests for all integrations

These changes ensure that when a request fails, the error response will accurately reflect which provider encountered the issue, with the error formatted according to that provider's API conventions. This is particularly important for applications that need to handle errors differently based on the provider that generated them.

The PR also adds a new test category for error handling, verifying that invalid role errors are properly detected and propagated through the system.
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.

2 participants