Skip to content

fix(storage): support AWS_S3_ADDRESSING_STYLE env var for S3 virtual/path addressing#9062

Open
mathcoder23 wants to merge 2 commits into
makeplane:previewfrom
mathcoder23:cody/fix-s3-virtual-address
Open

fix(storage): support AWS_S3_ADDRESSING_STYLE env var for S3 virtual/path addressing#9062
mathcoder23 wants to merge 2 commits into
makeplane:previewfrom
mathcoder23:cody/fix-s3-virtual-address

Conversation

@mathcoder23
Copy link
Copy Markdown

@mathcoder23 mathcoder23 commented May 13, 2026

Description

  • Some cloud storage service providers have limited compatibility with S3 path-style addressing, while modern providers predominantly use virtual-hosted style addressing. This caused "Error Loading Image" issues when uploading files through S3 storage.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Changes made:

  • Added AWS_S3_ADDRESSING_STYLE environment variable support (default: auto)
  • Supports three modes: auto, virtual, path
  • When set to virtual or path, configures botocore's Config(s3={"addressing_style": ...}) to control presigned URL format
  • Updated unit tests for the new addressing style configuration

Usage:

# Virtual-hosted style (https://bucket.s3.amazonaws.com/key)
AWS_S3_ADDRESSING_STYLE=virtual

# Path style (https://s3.amazonaws.com/bucket/key)
AWS_S3_ADDRESSING_STYLE=path

# Auto (let botocore decide) - default
AWS_S3_ADDRESSING_STYLE=auto

Notes:

  • This PR only modifies the boto3 S3 client in the S3Storage class. Other locations (such as export_task.py, exporter_expired_task.py, etc.) still use the original boto3 client creation method, which can be unified later if needed.
  • Impact: This PR uses a compatible approach to modify the code. Not introducing AWS_S3_ADDRESSING_STYLE environment variable will have no impact; existing deployments can upgrade normally.

Screenshots and Media (if applicable)

The issue with image uploads occurs when using S3 with a cloud storage provider that does not support path-style access mode.
image

Test Scenarios

image image

References

  • Issue: "Error Loading Image" when uploading files (V1.3.0)
  • Root cause: S3 client using path-style addressing incompatible with some cloud providers

Summary by CodeRabbit

  • New Features

    • Added configurable S3 addressing style support (virtual or path) to improve compatibility with different S3-compatible providers.
  • Tests

    • Added tests covering virtual, path, and default (auto) addressing behaviors, including a case for custom endpoint providers (e.g., DigitalOcean Spaces).

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1fd4fec-07d1-4692-b3b4-791927a2d6c3

📥 Commits

Reviewing files that changed from the base of the PR and between c279c31 and c97fc10.

📒 Files selected for processing (1)
  • apps/api/plane/settings/storage.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/plane/settings/storage.py

📝 Walkthrough

Walkthrough

S3Storage now imports botocore.config.Config and reads AWS_S3_ADDRESSING_STYLE during initialization to build a shared boto_config that sets signature_version and optionally configures s3.addressing_style. Both MinIO and non-MinIO boto3 clients use this unified config instead of ad-hoc configuration.

Changes

S3 Addressing Style Configuration

Layer / File(s) Summary
S3 addressing style configuration setup
apps/api/plane/settings/storage.py
S3Storage.__init__ reads AWS_S3_ADDRESSING_STYLE and constructs boto_config with signature_version="s3v4" and optional s3.addressing_style for virtual or path modes. Both MinIO and non-MinIO S3 client creations pass this shared config instead of constructing inline configuration.
S3 addressing style test coverage
apps/api/plane/tests/unit/settings/test_storage.py
New TestS3StorageAddressingStyle class verifies boto3 client configuration includes correct addressing_style values, defaults to botocore behavior when environment variable is unset, and properly forwards endpoint URLs with addressing style configuration.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 The S3 storage hops along with style,
Virtual or path, we'll go that mile,
Botocore configs now centralized and neat,
Tests confirm each addressing beat,
A little hop, a tidy feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding support for AWS_S3_ADDRESSING_STYLE environment variable for S3 addressing mode configuration.
Description check ✅ Passed The PR description is comprehensive and complete, covering all required template sections with detailed information about the change, motivation, usage examples, and test coverage.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

❤️ Share

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

@mathcoder23 mathcoder23 force-pushed the cody/fix-s3-virtual-address branch from 05d338f to c279c31 Compare May 13, 2026 06:39
@mathcoder23 mathcoder23 marked this pull request as ready for review May 13, 2026 06:42
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: 1

🧹 Nitpick comments (1)
apps/api/plane/tests/unit/settings/test_storage.py (1)

276-277: ⚡ Quick win

Avoid asserting on botocore private internals in tests.

_user_provided_options is a private attribute (prefixed with underscore) and is not part of botocore's documented public API, making this test brittle across botocore versions. Use the public Config.s3 dictionary instead—for example, assert that config.s3 is None when addressing_style is 'auto' (the default behavior).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/plane/tests/unit/settings/test_storage.py` around lines 276 - 277,
The test currently inspects botocore's private attribute _user_provided_options
(call_kwargs["config"]._user_provided_options) which is brittle; replace that
assertion with the public API by checking call_kwargs["config"].s3 is None when
addressing_style is 'auto' (or not set). Update the assertion in the
test_storage test that verifies S3 Config to use call_kwargs["config"].s3 is
None instead of inspecting the private _user_provided_options attribute.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/plane/settings/storage.py`:
- Around line 44-53: The code reads AWS_S3_ADDRESSING_STYLE but doesn't
normalize/validate it, so values like " Virtual " or typos silently fall back to
auto; update the retrieval of AWS_S3_ADDRESSING_STYLE to use .strip().lower(),
validate against the allowed set ("virtual","path","auto"), and if the value is
invalid log or raise a clear error before constructing boto_config; then use the
normalized addressing_style when building the Config (see addressing_style,
AWS_S3_ADDRESSING_STYLE, boto_config, Config).

---

Nitpick comments:
In `@apps/api/plane/tests/unit/settings/test_storage.py`:
- Around line 276-277: The test currently inspects botocore's private attribute
_user_provided_options (call_kwargs["config"]._user_provided_options) which is
brittle; replace that assertion with the public API by checking
call_kwargs["config"].s3 is None when addressing_style is 'auto' (or not set).
Update the assertion in the test_storage test that verifies S3 Config to use
call_kwargs["config"].s3 is None instead of inspecting the private
_user_provided_options attribute.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e530e5da-be20-4937-bd78-b80f264614c8

📥 Commits

Reviewing files that changed from the base of the PR and between 4225bc5 and c279c31.

📒 Files selected for processing (2)
  • apps/api/plane/settings/storage.py
  • apps/api/plane/tests/unit/settings/test_storage.py

Comment thread apps/api/plane/settings/storage.py Outdated
Comment on lines +44 to +53
addressing_style = os.environ.get("AWS_S3_ADDRESSING_STYLE", "auto").lower()

# Create boto3 Config with addressing style if explicitly set
if addressing_style in ("virtual", "path"):
boto_config = Config(
signature_version="s3v4",
s3={"addressing_style": addressing_style},
)
else:
boto_config = Config(signature_version="s3v4")
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize and validate AWS_S3_ADDRESSING_STYLE to avoid silent misconfiguration.

A value like " Virtual " or typo currently falls through to auto without any signal, which can hide config mistakes and make debugging provider-specific failures harder. Normalize with .strip().lower() and explicitly guard allowed values.

💡 Proposed fix
-        addressing_style = os.environ.get("AWS_S3_ADDRESSING_STYLE", "auto").lower()
+        addressing_style = os.environ.get("AWS_S3_ADDRESSING_STYLE", "auto").strip().lower()
+        if addressing_style not in {"auto", "virtual", "path"}:
+            raise ValueError(
+                "AWS_S3_ADDRESSING_STYLE must be one of: auto, virtual, path"
+            )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/plane/settings/storage.py` around lines 44 - 53, The code reads
AWS_S3_ADDRESSING_STYLE but doesn't normalize/validate it, so values like "
Virtual " or typos silently fall back to auto; update the retrieval of
AWS_S3_ADDRESSING_STYLE to use .strip().lower(), validate against the allowed
set ("virtual","path","auto"), and if the value is invalid log or raise a clear
error before constructing boto_config; then use the normalized addressing_style
when building the Config (see addressing_style, AWS_S3_ADDRESSING_STYLE,
boto_config, Config).

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 13, 2026

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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