Skip to content

Conversation

@pabloinigo
Copy link
Contributor

@pabloinigo pabloinigo commented Nov 3, 2025

Description

Summary

Fixes #35: Adds retry logic with exponential backoff to handle eventual consistency issues when reading vector store
files immediately after creation.

Problem

The OpenAI API experiences eventual consistency issues when reading a vector store file immediately after creation.
This causes Terraform to fail with errors like:

Error: Error reading vector store file: API error: No file found with id 'file-XXX' in vector store 'vs_XXX'.

This is particularly problematic when creating multiple vector store files simultaneously, as reported in issue #35.
The issue started occurring approximately 5 days before the bug report, suggesting a change in OpenAI's API behavior.

Solution

This PR implements an exponential backoff retry mechanism specifically for "file not found" errors during the read
operation after file creation:

  • Retry Logic: Up to 5 retry attempts with exponential backoff (1s, 2s, 4s, 8s, 16s)
  • Smart Error Handling: Only retries on "file not found" errors; other errors fail immediately
  • Enhanced Logging: Added detailed tflog statements to track file creation and retry attempts
  • Maximum Wait Time: ~31 seconds total (worst case scenario)

Changes

Code Changes

  • Added resourceOpenAIVectorStoreFileReadWithRetry() function with configurable retry logic
  • Enhanced logging throughout the create/read lifecycle
  • Modified resourceOpenAIVectorStoreFileCreate() to use retry logic on initial read

Tests Added

  • TestRetryLogicErrorDetection: Validates that retry logic correctly identifies retriable vs non-retriable errors
  • TestVectorStoreFileReadRetryLogic: Validates resource schema and retry behavior documentation
  • TestAccResourceOpenAIVectorStoreFile_basic: Acceptance test for basic file creation (skipped until credentials
    configured)
  • TestAccResourceOpenAIVectorStoreFile_retryLogic: Acceptance test for multi-file scenario (skipped until credentials
    configured)

Testing

Unit Tests

All unit tests pass:
go test -v ./internal/provider -run TestRetryLogicErrorDetection
go test -v ./internal/provider -run TestVectorStoreFileReadRetryLogic

Manual Testing

The fix can be manually tested by creating multiple vector store files simultaneously:
resource "openai_vector_store_file" "kb" {
for_each = openai_file.kb
vector_store_id = openai_vector_store.app_kb.id
file_id = each.value.id
}

Impact

  • Backwards Compatible: No breaking changes to the resource schema or behavior
  • Minimal Performance Impact: Only adds delays when errors occur
  • Improved Reliability: Handles transient API issues gracefully

Checklist

  • Code builds successfully
  • Unit tests added and passing
  • Acceptance tests added (will run when credentials are configured)
  • Follows existing code patterns and style
  • Enhanced logging for debugging

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce.

  • Unit tests
  • Acceptance tests
  • Manual testing

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

Release Notes

  • New Features

    • Added retry logic with exponential backoff for vector store file operations to improve reliability
    • Expanded Terraform examples covering embeddings, fine-tuning, vector stores, invitations, moderation, runs, service accounts, organization users, project management, and rate limiting
    • Added comprehensive documentation and data files for all example scenarios
  • Documentation

    • Added detailed guides and README files for all new example workflows and use cases

@pabloinigo pabloinigo added the bug Something isn't working label Nov 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Caution

Review failed

The head commit changed during the review from e100e7f to d28b7ec.

Walkthrough

The PR introduces retry logic with exponential backoff to the openai_vector_store_file resource to handle API eventual consistency issues after file creation. It adds comprehensive test coverage for the retry mechanism and includes extensive Terraform example documentation and configurations demonstrating multiple OpenAI provider features including embeddings, invitations, messages, runs, vector stores, and more.

Changes

Cohort / File(s) Summary
Provider Core Fix
internal/provider/resource_openai_vector_store_file.go, internal/provider/resource_openai_vector_store_file_retry_test.go
Adds retry-enabled read flow with exponential backoff (1s, 2s, 4s, 8s, 16s) to handle eventual consistency after vector store file creation. Introduces resourceOpenAIVectorStoreFileReadWithRetry() and containsRetriableError() helper. Enhances logging via tflog and imports time package. Includes comprehensive test suite covering success paths, retry scenarios, error handling, and exponential backoff timing validation.
Trivial Changes
.gitignore
Adds trailing blank line.
Documentation—Examples READMEs
examples/{embeddings,invite,messages,model_response,moderation,moderation_direct,organization_users,project_api,project_user,projects,rate_limit,run,service_account,upload,vector_store}/README.md
Comprehensive documentation for feature examples covering setup, prerequisites, usage patterns, import workflows, and common issues for embeddings, invitations, messages, model responses, moderation, organization users, project APIs, project users, projects, rate limits, runs, service accounts, file uploads, and vector stores.
Example Data Files (JSON/JSONL/Markdown/Text)
examples/files/data/{chat_requests_fixed,chat_requests_fixed2,embeddings_fixed}.jsonl, examples/fine_tuning/data/fine_tune_data_v4.jsonl, examples/fine_tuning/training_data/{sample_training,sample_validation}.jsonl, examples/image/output/simulated_image.txt, examples/messages/data/{sample_config.json,sample_document.txt}, examples/upload/fine_tuning_response.json, examples/upload/training_data.jsonl, examples/vector_store/files/{api_documentation,product_guide,support_faq}.md, examples/vector_store/test_file.txt
Sample datasets and documentation files for fine-tuning, batch operations, embeddings, image generation, messages, uploads, and vector store examples.
Example Terraform Configurations—Invitations
examples/invite/{main.tf,data_sources.tf}
Complete 3-step invitation workflow demonstrating user invitations, role assignments, project associations, and conditional resource creation with lifecycle management.
Example Terraform Configurations—Messages
examples/messages/{main.tf,retrieve_messages.tf}
Message creation and retrieval examples using threads, file attachments, metadata, module-based patterns, and data sources.
Example Terraform Configurations—Model Responses
examples/model_response/{main.tf,data_sources.tf,input_items.tf,model_response_data_source.tf,model_response_input_items_data_source.tf,model_responses_data_source.tf}
Demonstrates creating model responses with varied parameters, retrieving responses via data sources, paginating results, and accessing input items and usage metrics.
Example Terraform Configurations—Moderation
examples/moderation/{main.tf,README.md}, examples/moderation_direct/{main.tf,README.md}
Direct moderation resource examples with lifecycle patterns to ignore model version changes and outputs for flagged content detection.
Example Terraform Configurations—Organization & Project Users
examples/organization_users/{main.tf,email_lookup.tf}, examples/project_user/{main.tf,data_sources.tf,email_lookup.tf}
Organization and project user management with role-based assignment, email lookups, and module-based patterns for user retrieval and project membership.
Example Terraform Configurations—Projects & APIs
examples/projects/{main.tf,data_sources.tf,test.tf}, examples/project_api/{main.tf,import_project_key.sh}
Project creation and data retrieval, API key management with import automation via shell script.
Example Terraform Configurations—Rate Limits
examples/rate_limit/{main.tf,data_sources.tf}
Rate limit resource definition and data source retrieval examples with conditional usage and admin API key requirements.
Example Terraform Configurations—Runs
examples/run/{main.tf,main.tf.example,cleanup_active_runs.sh}, examples/run/backup/{main_fixed.tf,main_original.tf,runs_example.tf,test_simple.tf}
Comprehensive run examples demonstrating sequential thread/run creation, combined operations, pagination, ordering, and cleanup automation via shell script.
Example Terraform Configurations—Service Accounts
examples/service_account/{main.tf,data_sources.tf,run.sh}
Service account creation and data source retrieval with conditional toggling, permission error handling, and helper scripts.
Example Terraform Configurations—File Uploads
examples/upload/{main.tf,README.md}
File upload module usage for new uploads and imports with fine-tuning integration examples.
Example Terraform Configurations—Vector Stores
examples/vector_store/{main.tf,data_sources.tf,file.tf,outputs.tf,batch.tf,provider.tf}, examples/embeddings/{main.tf,README.md}
Vector store creation, file attachment, batch uploads, data source retrieval, and embeddings examples with metadata and module-based patterns.

Sequence Diagram

sequenceDiagram
    participant TF as Terraform
    participant Provider as Provider
    participant API as OpenAI API
    
    rect rgb(200, 220, 255)
    Note over TF,API: Create Vector Store File
    TF->>Provider: openai_vector_store_file create
    Provider->>API: POST /vector_stores/{id}/files
    API-->>Provider: file_id (queued)
    end
    
    rect rgb(220, 240, 200)
    Note over Provider,API: Retry-Enabled Read Flow (NEW)
    Provider->>Provider: readWithRetry(maxRetries=5)
    loop Exponential Backoff: 1s, 2s, 4s, 8s, 16s
        Provider->>API: GET /vector_stores/{id}/files/{file_id}
        alt Success
            API-->>Provider: file status=completed
            Provider-->>Provider: return success
        else Retriable Error (not found)
            API-->>Provider: 404 "not found"
            Provider->>Provider: wait & retry
        else Non-Retriable Error
            API-->>Provider: other error
            Provider-->>Provider: return error (no retry)
        end
    end
    end
    
    rect rgb(255, 240, 200)
    Note over Provider,TF: Resource State Updated
    Provider-->>TF: resource complete
    TF->>TF: state committed
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Attention areas:

  • Retry logic implementation (resource_openai_vector_store_file.go): Dense state management, exponential backoff calculations, error classification logic requiring careful verification against API behavior and edge cases.
  • Test coverage comprehensiveness (resource_openai_vector_store_file_retry_test.go): Validate timing assertions, mock behavior consistency, and edge case handling (zero/negative retries, immediate success, error categorization).
  • Example volume and correctness: 90+ new example files across 15+ feature areas; sample for correctness of provider syntax, resource attributes, data source usage, and realistic workflows.
  • Integration with existing read flow: Ensure new retry wrapper doesn't break existing non-create paths and that logging doesn't introduce verbosity regressions.

Poem

🐰 Whisker-twitch of joy! A file once lost, now found again
With backoff exponential, we retry and try at ten
Through vector stores and projects, examples bloom—five-fold more!
Retry logic refined, eventual consistency conquered—what a score! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Out of Scope Changes check ❓ Inconclusive Significant scope beyond issue #35: extensive example files (embeddings, fine_tuning, invite, messages, moderation, projects, etc.) and new test data appear disconnected from the retry logic fix. Clarify whether example/documentation files and test data are intentional additions for this PR or should be in a separate commit/PR focused on the retry logic fix.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: Error creating openai_vector_store_file resources' is directly related to the main change. It clearly identifies the core issue being fixed.
Description check ✅ Passed The PR description comprehensively covers the problem, solution, changes, tests, and impact. It follows the template structure with all major sections completed.
Linked Issues check ✅ Passed The PR directly addresses issue #35 by implementing exponential backoff retry logic for 'file not found' errors when creating vector store files, exactly matching the objectives.

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.

Copy link

@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)
internal/provider/resource_openai_vector_store_file_test.go (1)

215-224: Mirror the retry predicate’s case-insensitive check in tests

Once the production code normalizes error text, this test should do the same (and ideally add a "404 Not Found" sample) so the unit test continues to reflect the real retry gate. Suggested tweak:

-			// Check if error message contains retry-able patterns
-			shouldRetry := strings.Contains(tc.errorMsg, "No file found") ||
-				strings.Contains(tc.errorMsg, "not found")
+			msg := strings.ToLower(tc.errorMsg)
+			shouldRetry := strings.Contains(msg, "no file found") ||
+				strings.Contains(msg, "not found")

You can then add a new case with "404 Not Found" to lock in the regression test.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 739f75e and 26914d1.

📒 Files selected for processing (2)
  • internal/provider/resource_openai_vector_store_file.go (4 hunks)
  • internal/provider/resource_openai_vector_store_file_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
internal/provider/resource_openai_vector_store_file_test.go (1)
internal/client/client.go (1)
  • Error (206-210)

Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26914d1 and 583aa44.

📒 Files selected for processing (3)
  • .github/workflows/acceptance-tests.yml (1 hunks)
  • internal/provider/provider_test.go (1 hunks)
  • internal/provider/resource_openai_vector_store_file_retry_test.go (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
internal/provider/resource_openai_vector_store_file_retry_test.go

[error] 240-240: Test 'ZeroMaxRetries' in TestRetryLogicEdgeCases failed: Expected error when maxRetries=0.

🔇 Additional comments (2)
internal/provider/provider_test.go (1)

32-37: Optional org handling aligns with real-world setups.
Allowing acceptance tests to proceed without OPENAI_ORGANIZATION_ID matches the fact that many keys are tied to personal accounts, and the logging is helpful for debugging.

.github/workflows/acceptance-tests.yml (1)

31-60: CI guardrails look solid.
Thanks for wiring the dispatch/label gates, the API key checks, and the explicit warning when OPENAI_ORGANIZATION_ID is absent — that mirrors the provider’s new optional handling and keeps the job output clear. Pinning Terraform to the 1.12 line is reasonable today, though we should plan to validate against the current 1.13.x releases soon. (developer.hashicorp.com)

Copy link

@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

♻️ Duplicate comments (1)
internal/provider/resource_openai_vector_store_file_retry_test.go (1)

170-205: [Still unresolved] Past review comment not addressed: zero maxRetries silently succeeds.

The issue from the previous review remains unresolved. When maxRetries is 0, the for-loop (line 175) never executes, lastErr stays nil, and the function returns success instead of an error. This causes test misconfiguration to pass silently.

Apply the guard suggested in the past review:

 func simulateRetryLogic(readFunc mockReadFunc, maxRetries int) diag.Diagnostics {
+	if maxRetries <= 0 {
+		return diag.Errorf("maxRetries must be at least 1 for vector store file read retries")
+	}
+
 	ctx := context.Background()
 	d := &schema.ResourceData{}
 	var lastErr diag.Diagnostics
🧹 Nitpick comments (1)
internal/provider/resource_openai_vector_store_file_retry_test.go (1)

127-165: Consider increasing timing tolerance for CI stability.

The 200ms tolerance (line 154) and sub-second thresholds (lines 43, 122) may cause flakiness in resource-constrained CI environments. Consider increasing the tolerance to 500ms or using relative thresholds.

Apply this diff to increase tolerance:

-		tolerance := 200 * time.Millisecond
+		tolerance := 500 * time.Millisecond

And for quick-completion checks:

 		// Should complete almost immediately (no retries)
-		if elapsed > 500*time.Millisecond {
+		if elapsed > 1*time.Second {
 			t.Errorf("Expected to complete quickly, took %v", elapsed)
 		}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 583aa44 and 0a1e063.

📒 Files selected for processing (1)
  • internal/provider/resource_openai_vector_store_file_retry_test.go (1 hunks)

Copy link

@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 (3)
internal/provider/resource_openai_vector_store_file_test.go (3)

62-75: Consider verifying the resource exists via API.

The helper currently only validates that the resource ID exists in Terraform state without confirming the resource exists in the OpenAI API. While this is acceptable for basic scaffolding, consider making an actual API call to verify the resource exists when the tests are enabled, similar to the destroy check pattern used in testAccCheckOpenAIVectorStoreFileDestroy.

Example enhancement:

 func testAccCheckOpenAIVectorStoreFileExists(n string) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		rs, ok := s.RootModule().Resources[n]
 		if !ok {
 			return fmt.Errorf("Not found: %s", n)
 		}
 
 		if rs.Primary.ID == "" {
 			return fmt.Errorf("No vector store file ID is set")
 		}
+
+		// Verify the resource exists in the API
+		client := testClient()
+		vectorStoreID := rs.Primary.Attributes["vector_store_id"]
+		fileID := rs.Primary.ID
+		_, err := client.DoRequest("GET", fmt.Sprintf("/v1/vector_stores/%s/files/%s", vectorStoreID, fileID), nil)
+		if err != nil {
+			return fmt.Errorf("Vector store file %s does not exist: %s", fileID, err)
+		}
 
 		return nil
 	}
 }

162-191: Test name could be more descriptive.

The test function is named TestVectorStoreFileReadRetryLogic, but it primarily validates the resource schema rather than testing retry behavior. The comment on line 179 acknowledges this. Consider renaming to TestVectorStoreFileResourceSchema for clarity.

-func TestVectorStoreFileReadRetryLogic(t *testing.T) {
+func TestVectorStoreFileResourceSchema(t *testing.T) {
 	// Mock resource data
 	d := schema.TestResourceDataRaw(t, resourceOpenAIVectorStoreFile().Schema, map[string]interface{}{

195-240: Consider testing the actual retry detection function.

The test reimplements the retry detection logic inline (lines 231-232) rather than calling the actual implementation. This creates a risk: if the real retry logic in resourceOpenAIVectorStoreFileReadWithRetry changes, this test won't detect the discrepancy.

Consider extracting the retry detection logic into a testable helper function and calling it from both the production code and the test:

// In resource_openai_vector_store_file.go
func isRetriableError(err error) bool {
    if err == nil {
        return false
    }
    errMsg := err.Error()
    return strings.Contains(errMsg, "No file found") || 
           strings.Contains(errMsg, "not found")
}

// In test
func TestRetryLogicErrorDetection(t *testing.T) {
    // ...
    for _, tc := range testCases {
        t.Run(tc.name, func(t *testing.T) {
            err := errors.New(tc.errorMsg)
            shouldRetry := isRetriableError(err)
            
            if shouldRetry != tc.shouldRetry {
                t.Errorf("Expected shouldRetry=%v for error '%s', got %v",
                    tc.shouldRetry, tc.errorMsg, shouldRetry)
            }
        })
    }
}

Verify if such a function already exists:

#!/bin/bash
# Search for retry-related functions in the resource implementation
rg -n "func.*[Rr]etry|shouldRetry|isRetriable" --type=go internal/provider/resource_openai_vector_store_file.go
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a1e063 and 14ba514.

📒 Files selected for processing (2)
  • .github/workflows/acceptance-tests.yml (1 hunks)
  • internal/provider/resource_openai_vector_store_file_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
internal/provider/resource_openai_vector_store_file_test.go (1)
internal/client/client.go (1)
  • Error (206-210)
🔇 Additional comments (5)
.github/workflows/acceptance-tests.yml (4)

1-15: Well-designed workflow triggers.

The combination of manual dispatch with optional test filtering and automatic label-based triggering provides good flexibility for both ad-hoc and automated testing scenarios.


44-62: Excellent test execution configuration.

The test execution step includes:

  • Proper environment variable configuration for OpenAI credentials
  • Clear warnings about real resource creation and costs
  • Appropriate validation that fails fast on missing required credentials
  • Flexible test filtering via the TEST_FILTER variable

The implementation correctly handles both required (API key) and optional (Organization ID) credentials.


64-86: LGTM: PR feedback implementation.

The PR commenting logic correctly posts feedback only for pull request events (not manual dispatches) and uses clear, concise messaging with visual indicators.


36-39: The original review comment contains an incorrect premise.

Terraform 1.12 does exist, and as of November 3, 2025, the latest stable release is 1.13.4. The version 1.12.* specified in the workflow is a valid, released version and is available for use. The original concern that "this version may not exist yet" is unfounded.

While the workflow could optionally be updated to use the latest stable version (1.13.4) for access to newer features and bug fixes, the current specification is not incorrect or broken. Any decision to update should be based on project requirements and compatibility testing, not on the version being unavailable.

Likely an incorrect or invalid review comment.

internal/provider/resource_openai_vector_store_file_test.go (1)

77-101: No action required—testClient() is properly defined.

The testClient() function is defined in internal/provider/provider_test.go at line 41, making it available for use in the test file. The code is correct.

…ixes #35)

   Implements retry mechanism with exponential backoff to handle eventual consistency
   issues when the OpenAI API returns 'No file found' errors immediately after file
   creation in vector stores.

   Changes:
   - Add resourceOpenAIVectorStoreFileReadWithRetry wrapper with exponential backoff
   - Retry up to 5 times with delays: 1s, 2s, 4s, 8s, 16s (total ~31s max)
   - Case-insensitive error detection for 'not found' and 'no file found' errors
   - Guard against invalid maxRetries configuration (must be >= 1)
   - Enhanced logging with tflog for debugging retry attempts

   Testing:
   - Comprehensive unit tests for retry behavior and edge cases
   - Acceptance test infrastructure with secure GitHub Actions workflow
   - Test data files for file upload validation
   - Made OPENAI_ORGANIZATION_ID optional (supports personal accounts)

   All tests pass with proper timing validation.
@pabloinigo pabloinigo force-pushed the fix/issue-35-vector-store-file-read branch from 641b57d to a55f871 Compare November 3, 2025 19:20
Copy link

@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: 0

♻️ Duplicate comments (2)
internal/provider/resource_openai_vector_store_file_test.go (2)

103-119: Missing test data file: testdata/sample.txt

Line 110 references testdata/sample.txt which is not included in this PR. While the test is currently skipped, this file will be required when enabling the acceptance tests.

Please add the missing test data file before removing the skip annotation.


121-157: Missing test data file: testdata/sample2.txt

Line 133 references testdata/sample2.txt which is not included in this PR. This PR includes sample1.txt and sample3.txt but is missing sample2.txt. While the test is currently skipped, this file will be required when enabling the acceptance tests.

Please add the missing test data file to complete the test fixture set.

🧹 Nitpick comments (1)
internal/provider/resource_openai_vector_store_file_test.go (1)

195-240: Consider case-insensitive matching in error detection test.

The test uses case-sensitive string matching (lines 231-232), while the actual implementation in resource_openai_vector_store_file.go (lines 292-297) uses case-insensitive matching with strings.ToLower. This creates a discrepancy between test expectations and actual behavior.

Consider updating the test to match the actual implementation:

 		t.Run(tc.name, func(t *testing.T) {
 			// Check if error message contains retry-able patterns
-			shouldRetry := strings.Contains(tc.errorMsg, "No file found") ||
-				strings.Contains(tc.errorMsg, "not found")
+			lowerMsg := strings.ToLower(tc.errorMsg)
+			shouldRetry := strings.Contains(lowerMsg, "no file found") ||
+				strings.Contains(lowerMsg, "not found")
 
 			if shouldRetry != tc.shouldRetry {

This would ensure the test validates the actual behavior and would correctly handle test cases like "FILE NOT FOUND" and "404 Not Found".

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14ba514 and a55f871.

📒 Files selected for processing (9)
  • .github/workflows/acceptance-tests.yml (1 hunks)
  • internal/provider/provider_test.go (1 hunks)
  • internal/provider/resource_openai_vector_store_file.go (4 hunks)
  • internal/provider/resource_openai_vector_store_file_retry_test.go (1 hunks)
  • internal/provider/resource_openai_vector_store_file_test.go (1 hunks)
  • testdata/sample.txt (1 hunks)
  • testdata/sample1.txt (1 hunks)
  • testdata/sample2.txt (1 hunks)
  • testdata/sample3.txt (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • testdata/sample.txt
  • testdata/sample2.txt
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/acceptance-tests.yml
  • internal/provider/provider_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
internal/provider/resource_openai_vector_store_file_test.go (1)
internal/client/client.go (1)
  • Error (206-210)
🔇 Additional comments (14)
testdata/sample1.txt (1)

1-7: LGTM! Test data file is well-documented.

The file content clearly describes the test scenario and aligns with the PR's retry logic objectives.

testdata/sample3.txt (1)

1-10: LGTM! Test data file clearly documents expected behavior.

The retry timing documentation (1s, 2s, 4s, 8s, 16s) accurately reflects the exponential backoff implementation.

internal/provider/resource_openai_vector_store_file.go (5)

8-10: LGTM! Necessary imports for retry logic.

The time and tflog imports are properly used for exponential backoff delays and debug logging throughout the retry implementation.


237-243: LGTM! Helpful logging for debugging.

The debug and info logs provide good visibility into the file creation process and ID assignment, which will be valuable for troubleshooting eventual consistency issues.


266-268: LGTM! Retry logic correctly applied after creation.

Using resourceOpenAIVectorStoreFileReadWithRetry with 5 retries addresses the eventual consistency issue described in the PR objectives. The approach maintains Terraform lifecycle semantics while handling transient API failures.


270-315: LGTM! Robust retry implementation with proper error handling.

The retry function correctly implements:

  • Exponential backoff with appropriate delays (1s, 2s, 4s, 8s, 16s)
  • Case-insensitive error detection (addresses past review concern about "404 Not Found" variants)
  • Fast-fail for non-retryable errors (auth, rate limits, etc.)
  • Comprehensive logging at each retry stage

The implementation aligns well with the PR objectives and handles the OpenAI API's eventual consistency behavior.


324-332: LGTM! Read function properly uses resource ID.

The modifications correctly use d.Id() for the file ID and add helpful debug/error logging. This aligns with Terraform resource patterns and improves troubleshooting capabilities.

internal/provider/resource_openai_vector_store_file_test.go (2)

13-60: LGTM! Well-structured acceptance tests.

Both test cases follow Terraform provider testing best practices:

  • Proper use of PreCheck and ProviderFactories
  • Appropriate existence and destruction checks
  • Comprehensive attribute validation

The skip guards are sensible until API credentials are configured for CI.


62-101: LGTM! Helper functions properly validate resource lifecycle.

The existence and destroy check functions correctly:

  • Validate resource state presence
  • Make API calls to verify actual deletion
  • Use case-insensitive error matching for 404/not found responses
  • Distinguish between expected (404) and unexpected errors
internal/provider/resource_openai_vector_store_file_retry_test.go (5)

18-166: LGTM! Comprehensive retry behavior testing.

The test scenarios thoroughly validate:

  • Immediate success without unnecessary retries
  • Correct retry count after transient failures
  • Exhaustion of all retries for persistent failures
  • Fast-fail for non-retriable errors
  • Accurate exponential backoff timing

Timing assertions use appropriate tolerances to account for test execution overhead while still catching timing regressions.


170-209: LGTM! Retry simulation properly guards against invalid configuration.

The function now includes the guard clause for maxRetries <= 0 (lines 171-173), addressing the past review concern. The simulation accurately mirrors the actual retry logic in resource_openai_vector_store_file.go, including:

  • Exponential backoff calculation
  • Retriable error detection
  • Early exit for non-retriable errors

213-216: LGTM! Error detection properly handles case variations.

The case-insensitive matching correctly identifies retriable errors across different formats ("No file found", "404 Not Found", "FILE NOT FOUND", etc.), matching the actual implementation.


230-304: LGTM! Comprehensive edge case coverage.

The edge case tests now include all scenarios requested in past reviews:

  • Zero and negative maxRetries validation (lines 232-259)
  • Single retry behavior (lines 261-277)
  • Case-insensitive error message matching with extensive test cases (lines 279-303)

The test cases cover both retriable and non-retriable error patterns, ensuring robust error handling.


219-228: LGTM! Useful performance baseline.

The benchmark provides a baseline for the retry logic's happy path (immediate success), which helps identify performance regressions in future changes.

Copy link

@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: 0

🧹 Nitpick comments (2)
internal/provider/resource_openai_vector_store_file.go (2)

266-270: LGTM! Consider making retry count configurable.

The retry logic correctly addresses issue #35. The hardcoded maxRetries=5 provides a reasonable default (~31s max wait), but consider making this configurable via provider configuration or environment variable in a future enhancement for users with different latency requirements.


272-310: LGTM! Add parameter validation.

The retry loop and exponential backoff logic are correctly implemented. However, add validation for the maxRetries parameter.

Apply this diff to add validation:

 func resourceOpenAIVectorStoreFileReadWithRetry(ctx context.Context, d *schema.ResourceData, m interface{}, maxRetries int) diag.Diagnostics {
+	if maxRetries < 1 {
+		return diag.Errorf("maxRetries must be at least 1, got: %d", maxRetries)
+	}
+
 	var lastErr diag.Diagnostics
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a55f871 and f7bfeaf.

📒 Files selected for processing (2)
  • .gitignore (1 hunks)
  • internal/provider/resource_openai_vector_store_file.go (4 hunks)
🔇 Additional comments (7)
.gitignore (1)

168-169: Verify that ignoring the entire examples/ directory aligns with project intent.

The change adds a blanket ignore for examples/, but line 46 already has a specific entry: terraform-provider-openai/examples/basic/terraform.tfvars. Before merging, clarify:

  1. Should the entire examples/ directory be ignored, or only specific test artifacts within it?
  2. Are there example files that should remain committed to the repository (e.g., documentation or reference examples)?
  3. Does the new entry at line 169 make the line 46 entry redundant, or do they serve different purposes?

This is particularly important if the examples/ directory contains reference or documentation files that should be part of the repository.

internal/provider/resource_openai_vector_store_file.go (6)

8-10: LGTM!

The import additions are appropriate for the retry logic and structured logging being introduced.


237-243: LGTM!

The structured logging adds valuable observability for debugging file creation and ID assignment.


311-324: LGTM! Case-insensitive matching correctly implemented.

The case-insensitive error detection correctly addresses the previous review feedback and will catch both "No file found" and "404 Not Found" error variants.


325-338: LGTM!

The retry exit logic correctly distinguishes between retriable and non-retriable errors, returning immediately for non-transient failures while logging retry attempts for eventual consistency issues.


352-355: LGTM!

The error logging provides helpful debugging context when read operations fail.


347-349: I need to examine the codebase to understand what ID is actually being stored in the resource.

Based on the web search results, I can now provide a comprehensive assessment.

The OpenAI API returns a file object with an "id" field (e.g., "file-Z80edd3ZDAkbrm43V...."), and the API expects you to pass the file_id parameter when attaching files to a vector store.

The change from d.Get("file_id") to d.Id() is correct and important:

  • The resource's ID should be the file ID returned by the API ("file-" format), which is what d.Id() provides
  • d.Get("file_id") retrieves the user-provided input field, which may diverge from the authoritative ID managed by the API
  • Using d.Id() ensures you're using the canonical resource identifier for all subsequent API calls, including the read/retrieve operation

The logging additions are also appropriate for debugging resource state. The code change is correct.

t.Logf("Using organization ID: %s", v)
} else {
t.Log("No organization ID set - using personal account")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is changing this test file really required in this PR?

@Fodoj
Copy link
Contributor

Fodoj commented Nov 11, 2025

PR title doesn't reflect what PR is doing

Copy link

@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: 0

🧹 Nitpick comments (1)
internal/provider/resource_openai_vector_store_file_retry_test.go (1)

74-74: Consider increasing timing tolerances for CI stability.

The timing assertions at lines 74 (2-4 second range for ~3s backoff) and 154 (200ms tolerance) might be too tight for CI environments where systems can be under heavy load, potentially causing flaky test failures.

Consider widening the tolerances:

-		if elapsed < 2*time.Second || elapsed > 4*time.Second {
+		if elapsed < 2*time.Second || elapsed > 5*time.Second {
-		tolerance := 200 * time.Millisecond
+		tolerance := 500 * time.Millisecond

Also applies to: 154-154

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7bfeaf and 73a6511.

📒 Files selected for processing (2)
  • internal/provider/resource_openai_vector_store_file.go (4 hunks)
  • internal/provider/resource_openai_vector_store_file_retry_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/provider/resource_openai_vector_store_file.go
🔇 Additional comments (3)
internal/provider/resource_openai_vector_store_file_retry_test.go (3)

17-166: Comprehensive test coverage for retry behavior.

The test suite covers all critical scenarios: immediate success, success after retries, max retries exhausted, non-retriable errors, and exponential backoff timing. The structure with clear subtests and call count tracking is excellent.


223-297: Excellent edge case coverage.

The edge cases test thoroughly validates invalid configurations (zero/negative maxRetries), boundary conditions (single retry), and case-insensitive error matching. The test cases in ErrorMessageCaseInsensitivity appropriately distinguish between retriable and non-retriable errors.


194-194: No issues found - verification confirms containsRetriableError is properly accessible.

The function containsRetriableError is defined at line 274 in internal/provider/resource_openai_vector_store_file.go. Since both the test file and production file are in the same internal/provider/ package, the test can access this function without any issues.

   Remove the OPENAI_ORGANIZATION_ID optional changes from provider_test.go
   as they are not related to the retry logic fix for issue #35.
   This change should be addressed in a separate PR if needed.

   Addresses feedback from @Fodoj in PR #37
@pabloinigo pabloinigo requested a review from Fodoj November 14, 2025 08:31
@Fodoj
Copy link
Contributor

Fodoj commented Nov 14, 2025

@pabloinigo could you please adjust the PR title?

@pabloinigo pabloinigo changed the title Added test fix: Error creating openai_vector_store_file resources Nov 19, 2025
Copy link

@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: 28

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/invite/README.md (1)

230-250: Fix markdown style issues in the data sources section.

Line 234 uses emphasis (**...Important**) instead of a proper heading. Consider using a proper Markdown heading syntax. Additionally, line 341 has a fenced code block without a language identifier.

Apply this diff to improve the markdown structure:

-### Data Source: openai_project_users
-
-This data source retrieves information about all users within a specific project.
-
-**Important: Never output the entire data source directly**
+### Data Source: openai_project_users
+
+This data source retrieves information about all users within a specific project.
+
+#### Important: Never output the entire data source directly

And for line 341:

-    ```
+    ```json
     { "role": "member" }
-    ```
+    ```
🧹 Nitpick comments (23)
examples/moderation_direct/main.tf (1)

80-80: Remove trailing whitespace.

Line 80 has a trailing space after the closing brace that should be removed for formatting consistency.

-} 
+}
examples/rate_limit/README.md (1)

44-65: Refine repeated use of "right" for better readability.

The permissions section uses "right" twice in nearby sentences (lines 46 and 60). Consider rephrasing one occurrence for better writing clarity.

Apply this diff to improve word variety:

- If you don't have the right permissions, the data sources will fail with a permissions error, but the example will still work for setting rate limits through the resources.
+ If you lack the required permissions, the data sources will fail with a permissions error, but the example will still work for setting rate limits through the resources.
examples/fine_tuning/training_data/sample_validation.jsonl (1)

4-4: Remove trailing whitespace.

Line 4 has trailing whitespace after the closing brace. For consistency with lines 1-3, please remove it.

examples/project_api/import_project_key.sh (1)

207-211: Auto-approve is reasonable for this workflow but consider adding confirmation.

The script provides clear messaging before auto-applying, which is appropriate for an import workflow. However, consider adding an optional confirmation prompt to let users review the generated main.tf before applying, in case they notice issues.

examples/invite/README.md (1)

100-125: Helpful provider code fix example.

The provider code fix section (lines 102-122) demonstrates good error handling for the "already accepted" deletion error case. Consider adding a note that this pattern should be reviewed against the actual provider implementation to ensure synchronization.

Consider adding a disclaimer:

 ## Provider Code Fix
 
 The provider's client code has been updated to handle "already accepted" errors during deletion:
+
+**Note: Verify this implementation against the current provider codebase to ensure it's up to date.**
examples/organization_users/main.tf (2)

48-53: Replace hardcoded user ID with a variable for example reusability.

The user ID is hardcoded, making this example harder for users to adapt. Consider extracting it to a variable with a comment explaining how to obtain a real user ID.

variable "organization_user_id" {
  description = "ID of the user to retrieve. Replace with a real user ID from your organization."
  type        = string
  default     = "user-udjrDA1SqpU8CnkH28BGq5JY" # Replace this with a real user ID
}

data "openai_organization_user" "specific" {
  count   = var.enable_organization_users ? 1 : 0
  user_id = var.organization_user_id
}

61-66: Remove unreachable hardcoded user ID fallback.

Line 64 contains a hardcoded fallback "user-abc123xyz" that is unreachable because the resource only creates when var.enable_organization_users is true, which also guards the data source. Simplify to remove the dead code path.

 resource "openai_project_user" "specific_user" {
   count      = var.enable_organization_users ? 1 : 0
   project_id = openai_project.example.id
-  user_id    = var.enable_organization_users ? data.openai_organization_user.specific[0].id : "user-abc123xyz"
+  user_id    = data.openai_organization_user.specific[0].id
   role       = "owner"
 }
examples/invite/data_sources.tf (2)

11-22: Extract hardcoded email to a variable for example reusability.

The email address is hardcoded, making it difficult for users to adapt this example. Extract it to a variable with a descriptive name and default.

+# Email to use for the example invitation
+variable "example_invite_email" {
+  description = "Email address for the example invitation"
+  type        = string
+  default     = "someone-new-example-a@example.com"
+}
+
 resource "openai_invite" "example_invite_data" {
   count = var.create_example_invite ? 1 : 0

-  email = "someone-new-example-a@example.com"
+  email = var.example_invite_email
   role  = "reader" # Can be "owner" or "reader"

49-78: Consider using null instead of "example_invite_disabled" string fallback.

The fallback string "example_invite_disabled" is not idiomatic Terraform. When the feature is disabled, consider using null or returning the data conditionally to avoid confusion about what the output actually represents.

 output "invite_id" {
   description = "ID of the invitation"
-  value       = var.create_example_invite ? data.openai_invite.invitation_details[0].id : "example_invite_disabled"
+  value       = try(data.openai_invite.invitation_details[0].id, null)
 }

This way, Terraform users understand that a null output means the feature was disabled, and they won't accidentally use the sentinel string value.

examples/project_user/data_sources.tf (2)

10-17: Extract hardcoded user ID to a variable for example reusability.

The user ID is hardcoded, making this example less adaptable. Extract it to a variable so users can easily customize it with their own organization user IDs.

+# User ID from your organization to demonstrate project user operations
+variable "example_user_id" {
+  description = "Real user ID from your organization"
+  type        = string
+  default     = "user-yatSd6LuWvgeoqZbd89xzPlJ" # Replace with a real user ID
+}
+
 resource "openai_project_user" "data_source_user" {
   project_id = openai_project.data_source_example.id
-  user_id    = "user-yatSd6LuWvgeoqZbd89xzPlJ" # Real user ID from your organization
+  user_id    = var.example_user_id
   role       = "owner"

19-22: Use the same variable for organization user lookup (consistency with refactor).

Line 21 also contains the hardcoded user ID. When refactoring line 13 to use a variable, update this data source to use the same variable for consistency.

 data "openai_organization_user" "user_info" {
-  user_id = "user-yatSd6LuWvgeoqZbd89xzPlJ" # Real user ID from your organization
+  user_id = var.example_user_id
 }
examples/embeddings/README.md (1)

68-102: Clarify import limitations and workaround approach.

The "Import Limitations" section (lines 72-86) describes a workaround using "simulated embeddings" and "fault-tolerant structure," but these terms are vague. Additionally, line 93 states that applying after import will replace the resource, which seems to contradict the purpose of importing.

Consider:

  1. Clarifying what "simulated embeddings" means in concrete terms
  2. Explaining whether import is recommended or if it has significant caveats
  3. Documenting the exact behavior users should expect after import + apply
examples/upload/main.tf (1)

28-31: Remove unused local variable.

The training_file_path local variable is defined but never used. Line 40 hardcodes the path instead of referencing this variable.

Apply this diff to either remove the unused variable or use it:

-# Local variables for file properties
-locals {
-  # Path to the training data file
-  training_file_path = "${path.module}/training_data.jsonl"
-}
-
 # Use the upload module to manage the file
 # This module works with both new uploads and imports
 module "fine_tune_upload" {
   source = "../../modules/upload"
 
   # Required attributes
   purpose   = "fine-tune"
-  file_path = "./training_data.jsonl"
+  file_path = "${path.module}/training_data.jsonl"

Or simply remove the unused locals block if the hardcoded path is preferred.

examples/upload/README.md (2)

103-119: Add language specifiers to code blocks.

Multiple shell code blocks are missing language specifiers, which reduces readability and prevents proper syntax highlighting.

Apply these diffs to add bash language specifiers:

    ```
+   ```bash
    export OPENAI_API_KEY=your_api_key_here
    ```
 
    ```
+   ```bash
    terraform init
    ```
 
    ```
+   ```bash
    terraform apply
    ```
 
    ```
+   ```bash
    terraform output file_id
    ```

153-161: Add language specifiers to cleanup code blocks.

The cleanup section code blocks are missing language specifiers.

Apply this diff:

 To destroy the resources created by Terraform:

+```bash
terraform destroy


Note that this will not delete the file from OpenAI. To delete the file, you need to call the OpenAI API:

+```bash
curl -X DELETE https://api.openai.com/v1/files/$(terraform output -raw file_id)
-H "Authorization: Bearer $OPENAI_API_KEY"

examples/model_response/README.md (1)

227-227: Consider tightening the phrasing around resource preservation.

Line 227 could be more concise: change "If you want to make changes to your configuration file after importing, the provider will detect drift but won't recreate the resource, preserving your original output." to something like "After importing, configuration changes won't recreate the resource, preserving the original output."

examples/service_account/run.sh (1)

1-17: Add error handling and prefer environment variables for sensitive inputs.

The script uses -auto-approve without error handling, so failures go undetected. Additionally, passing the API key as a command-line argument makes it visible in process listings; use environment variables instead (e.g., TF_VAR_openai_admin_key).

 #!/bin/bash
+set -e  # Exit on any error
+
 # Check if admin key is provided
 if [ -z "$1" ]; then
   echo "Usage: ./run.sh YOUR_OPENAI_ADMIN_KEY"
   echo "Example: ./run.sh sk-your-openai-admin-key"
   exit 1
 fi

-# Store the admin key in a variable
-OPENAI_ADMIN_KEY="$1"
+# For better security, use environment variable instead:
+# export TF_VAR_openai_admin_key="sk-admin-..."
+# Then call: ./run.sh
+if [ -z "$TF_VAR_openai_admin_key" ]; then
+  export TF_VAR_openai_admin_key="$1"
+fi

 # Run terraform apply with the admin key
 terraform apply \
   -var="try_create_service_account=true" \
   -var="try_data_sources=false" \
-  -var="openai_admin_key=$OPENAI_ADMIN_KEY" \
-  -auto-approve
+  -auto-approve
examples/service_account/README.md (2)

105-114: Remove redundant "explicitly" adverbs in the list.

Line 110 repeats the word "explicitly" in consecutive bullet points, which is redundant.

 This design allows you to run the examples even without all permissions and see what would happen if you had the right permissions.
-
-1. Resources are only created when explicitly enabled
-2. Data sources are only queried when explicitly enabled
-3. Fallback values are used for all outputs when permissions are missing
-4. Dependencies are carefully managed to ensure data sources are only accessed after resources are created
+
+1. Resources are only created when explicitly enabled
+2. Data sources are only queried when needed
+3. Fallback values are used for all outputs when permissions are missing
+4. Dependencies are carefully managed to ensure data sources are only accessed after resources are created

91-103: Clarify that the curl example is a template.

Add a note that the curl command is a template and that users should replace placeholder values with actual credentials.

 ## Verifying Your Admin Key
 
 You can verify that your admin key has the correct permissions by using curl:
 
 ```bash
+# NOTE: This is a template. Replace placeholders with actual values.
 # Check if you can access a service account
 curl https://api.openai.com/v1/organization/projects/YOUR_PROJECT_ID/service_accounts/YOUR_SERVICE_ACCOUNT_ID \
   -H "Authorization: Bearer YOUR_ADMIN_KEY" \
examples/projects/data_sources.tf (1)

12-12: Consider whether explicit depends_on is necessary.

The configuration explicitly includes depends_on = [openai_project.example] for both data sources (lines 12, 17). Terraform's implicit dependency tracking via openai_project.example.id in the openai_project data source should be sufficient. The depends_on on the openai_projects data source may be intentional for timing reasons, but verify if it's needed or if it could be removed for clarity.

Also applies to: 17-17

examples/projects/README.md (1)

1-44: README setup and documentation structure is clear and professional.

The documentation provides appropriate context, prerequisites, setup instructions, and usage workflows. The terraform.tfvars approach for credential management is documented (lines 26-30), though the examples in main.tf rely on environment variables instead. Consider clarifying the relationship between these two approaches.

Clarify the credential setup documentation by noting that the examples use environment variables (OPENAI_API_KEY, OPENAI_ADMIN_KEY) rather than terraform.tfvars. You could add a note about both approaches:

## Setup Options

### Option 1: Environment Variables (Recommended)
```bash
export OPENAI_API_KEY="sk-xxxx"
export OPENAI_ADMIN_KEY="sk-xxxx"
terraform apply

Option 2: terraform.tfvars

Create a terraform.tfvars file with your credentials (do not commit to VCS).


</blockquote></details>
<details>
<summary>examples/run/cleanup_active_runs.sh (1)</summary><blockquote>

`46-46`: **Simplify jq command to avoid useless use of cat.**

The pattern `cat file | jq` is inefficient. `jq` can read files directly.



Apply this diff:

```diff
-    thread_ids=$(cat terraform.tfstate | jq -r '.resources[]? | select(.type == "openai_thread") | .instances[].attributes.id' 2>/dev/null)
+    thread_ids=$(jq -r '.resources[]? | select(.type == "openai_thread") | .instances[].attributes.id' terraform.tfstate 2>/dev/null)
examples/run/main.tf.example (1)

1-149: Clarify the purpose of .example files.

Files with .example extensions typically indicate template files that users should copy and customize. However, this file is much more complex than main.tf and includes features (custom functions, multiple tool types, module usage) that may overwhelm users looking for a basic example.

Consider one of these approaches:

  1. If this is meant to be a comprehensive reference: Rename to something like advanced.tf or comprehensive.tf
  2. If it's meant to be a template: Add comments explaining what users should customize
  3. If it's redundant: Remove it in favor of the simpler main.tf

Also add a README in examples/run/ explaining which example file serves which purpose.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73a6511 and 9bf8f9c.

⛔ Files ignored due to path filters (6)
  • examples/audio/output/prueba_directorio_original.mp3 is excluded by !**/*.mp3
  • examples/audio/output/speech.mp3 is excluded by !**/*.mp3
  • examples/audio/output/test_speech.mp3 is excluded by !**/*.mp3
  • examples/audio/samples/speech.mp3 is excluded by !**/*.mp3
  • examples/image/output/edited_image_18043.png is excluded by !**/*.png
  • examples/messages/data/sample_data.csv is excluded by !**/*.csv
📒 Files selected for processing (73)
  • .gitignore (1 hunks)
  • examples/embeddings/README.md (1 hunks)
  • examples/embeddings/main.tf (1 hunks)
  • examples/files/data/chat_requests_fixed.jsonl (1 hunks)
  • examples/files/data/chat_requests_fixed2.jsonl (1 hunks)
  • examples/files/data/embeddings_fixed.jsonl (1 hunks)
  • examples/fine_tuning/data/fine_tune_data_v4.jsonl (1 hunks)
  • examples/fine_tuning/training_data/sample_training.jsonl (1 hunks)
  • examples/fine_tuning/training_data/sample_validation.jsonl (1 hunks)
  • examples/image/output/simulated_image.txt (1 hunks)
  • examples/invite/README.md (1 hunks)
  • examples/invite/data_sources.tf (1 hunks)
  • examples/invite/main.tf (1 hunks)
  • examples/messages/README.md (1 hunks)
  • examples/messages/data/sample_config.json (1 hunks)
  • examples/messages/data/sample_document.txt (1 hunks)
  • examples/messages/main.tf (1 hunks)
  • examples/messages/retrieve_messages.tf (1 hunks)
  • examples/model_response/README.md (1 hunks)
  • examples/model_response/data_sources.tf (1 hunks)
  • examples/model_response/input_items.tf (1 hunks)
  • examples/model_response/main.tf (1 hunks)
  • examples/model_response/model_response_data_source.tf (1 hunks)
  • examples/model_response/model_response_input_items_data_source.tf (1 hunks)
  • examples/model_response/model_responses_data_source.tf (1 hunks)
  • examples/moderation/README.md (1 hunks)
  • examples/moderation/main.tf (1 hunks)
  • examples/moderation_direct/README.md (1 hunks)
  • examples/moderation_direct/main.tf (1 hunks)
  • examples/organization_users/README.md (1 hunks)
  • examples/organization_users/email_lookup.tf (1 hunks)
  • examples/organization_users/main.tf (1 hunks)
  • examples/project_api/README.md (1 hunks)
  • examples/project_api/import_project_key.sh (1 hunks)
  • examples/project_api/main.tf (1 hunks)
  • examples/project_user/README.md (1 hunks)
  • examples/project_user/data_sources.tf (1 hunks)
  • examples/project_user/email_lookup.tf (1 hunks)
  • examples/project_user/main.tf (1 hunks)
  • examples/projects/README.md (1 hunks)
  • examples/projects/data_sources.tf (1 hunks)
  • examples/projects/main.tf (1 hunks)
  • examples/projects/test.tf (1 hunks)
  • examples/rate_limit/README.md (1 hunks)
  • examples/rate_limit/data_sources.tf (1 hunks)
  • examples/rate_limit/main.tf (1 hunks)
  • examples/run/README.md (1 hunks)
  • examples/run/backup/main_fixed.tf (1 hunks)
  • examples/run/backup/main_original.tf (1 hunks)
  • examples/run/backup/runs_example.tf (1 hunks)
  • examples/run/backup/test_simple.tf (1 hunks)
  • examples/run/cleanup_active_runs.sh (1 hunks)
  • examples/run/main.tf (1 hunks)
  • examples/run/main.tf.example (1 hunks)
  • examples/service_account/README.md (1 hunks)
  • examples/service_account/data_sources.tf (1 hunks)
  • examples/service_account/main.tf (1 hunks)
  • examples/service_account/run.sh (1 hunks)
  • examples/upload/README.md (1 hunks)
  • examples/upload/fine_tuning_response.json (1 hunks)
  • examples/upload/main.tf (1 hunks)
  • examples/upload/training_data.jsonl (1 hunks)
  • examples/vector_store/README.md (1 hunks)
  • examples/vector_store/batch.tf (1 hunks)
  • examples/vector_store/data_sources.tf (1 hunks)
  • examples/vector_store/file.tf (1 hunks)
  • examples/vector_store/files/api_documentation.md (1 hunks)
  • examples/vector_store/files/product_guide.md (1 hunks)
  • examples/vector_store/files/support_faq.md (1 hunks)
  • examples/vector_store/main.tf (1 hunks)
  • examples/vector_store/outputs.tf (1 hunks)
  • examples/vector_store/provider.tf (1 hunks)
  • examples/vector_store/test_file.txt (1 hunks)
✅ Files skipped from review due to trivial changes (15)
  • examples/messages/README.md
  • examples/files/data/chat_requests_fixed.jsonl
  • examples/files/data/embeddings_fixed.jsonl
  • examples/fine_tuning/training_data/sample_training.jsonl
  • examples/run/README.md
  • examples/vector_store/test_file.txt
  • examples/model_response/model_responses_data_source.tf
  • examples/moderation_direct/README.md
  • examples/upload/fine_tuning_response.json
  • examples/vector_store/provider.tf
  • .gitignore
  • examples/messages/retrieve_messages.tf
  • examples/model_response/input_items.tf
  • examples/messages/data/sample_document.txt
  • examples/model_response/data_sources.tf
🧰 Additional context used
🪛 Gitleaks (8.29.0)
examples/service_account/README.md

[high] 93-98: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

examples/vector_store/files/product_guide.md

[high] 76-77: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🪛 LanguageTool
examples/vector_store/files/support_faq.md

[grammar] ~17-~17: Use a hyphen to join words.
Context: ...ited to 60 requests per minute. Standard tier accounts are limited to 600 request...

(QB_NEW_EN_HYPHEN)

examples/service_account/README.md

[grammar] ~45-~45: Ensure spelling is correct
Context: ...e both creation and reading in the same apply: bash terraform apply -var="try_create_service_account=true" -var="try_data_sources=true" -var="openai_admin_key=sk-admin-..." ### Helper Script A convenient run.sh scr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~110-~110: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ... explicitly enabled 2. Data sources are only queried when explicitly enabled 3. Fall...

(ADVERB_REPETITION_PREMIUM)

examples/invite/README.md

[style] ~147-~147: The noun “invitation” is usually used instead of ‘invite’ in formal writing.
Context: ...er" } ### Custom API Key Invite An invite using a custom API key:hcl resource...

(AN_INVITE)

examples/model_response/README.md

[style] ~227-~227: Consider shortening or rephrasing this to strengthen your wording.
Context: ...ponse.resource_name ``` If you want to make changes to your configuration file after importing...

(MAKE_CHANGES)

examples/rate_limit/README.md

[style] ~60-~60: You have already used ‘right’ in nearby sentences. Consider using an alternative word to let your writing stand out and sound more polished.
Context: ...k-admin-..." ``` If you don't have the right permissions, the data sources will fail...

(REP_RIGHT)

🪛 markdownlint-cli2 (0.18.1)
examples/moderation/README.md

107-107: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


128-128: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


135-135: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


146-146: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


180-180: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/project_user/README.md

234-234: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


341-341: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/vector_store/files/api_documentation.md

11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/upload/README.md

100-100: Multiple headings with the same content

(MD024, no-duplicate-heading)


103-103: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


108-108: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


113-113: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


118-118: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


153-153: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


159-159: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/model_response/README.md

155-155: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


160-160: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


165-165: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


179-179: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/organization_users/README.md

75-75: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


85-85: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

examples/project_api/README.md

75-75: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


115-115: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (61)
examples/messages/data/sample_config.json (1)

1-15: Example configuration file looks good.

The JSON structure is valid and well-formed. This serves as a useful reference configuration for the messaging example workflow. No issues with the content or structure.

examples/files/data/chat_requests_fixed2.jsonl (1)

1-3: JSONL examples look consistent and valid

All three lines are valid JSON objects, follow a consistent chat request shape (model/custom_id/method/messages), and are appropriate as example data alongside the existing chat_requests_fixed.jsonl. No issues from a schema or usability perspective.

examples/image/output/simulated_image.txt (1)

1-10: Scope concern: This file appears tangential to the stated PR objectives.

The PR objectives focus on vector store file retry logic (Go code changes), while this file is example documentation for image generation. Although the AI summary mentions "extensive Terraform example documentation," the explicit PR objectives don't reference image examples.

Please clarify whether this file is intentional and in scope, or if it was included unintentionally.

examples/moderation/README.md (1)

1-250: Content quality is excellent.

The documentation is comprehensive, well-structured, and provides clear guidance on moderation usage patterns, import workflows, and API limitations. The dual approach to model version handling (provider-level and resource-level lifecycle blocks) is well-explained and defensively coded. Examples are concrete and directly applicable.

examples/moderation/main.tf (1)

1-90: Configuration is well-structured and follows best practices.

The Terraform configuration consistently applies per-resource lifecycle blocks to handle model version differences. Resource declarations are clear with appropriate input examples. Output definitions properly map to both individual and batch moderation results with descriptive labels.

examples/moderation_direct/main.tf (1)

1-80: Configuration is well-structured and consistent with the moderation example.

The direct moderation example follows the same established patterns: per-resource lifecycle blocks, consistent output naming with the direct_ prefix, and descriptive labels. The three examples demonstrate a straightforward usage pattern without modules.

examples/rate_limit/data_sources.tf (1)

1-72: Well-structured data sources with appropriate conditional logic.

The data sources are correctly configured with count conditions to make them optional, and the outputs properly reference the conditional data source instances. The error handling documentation accurately reflects the PR's improvements for graceful authentication failure handling.

examples/rate_limit/main.tf (2)

17-21: Verify hardcoded project_id is clearly documented as a placeholder.

The default project_id value appears to be a real OpenAI project ID format. If this is an actual project, consider removing it as a default or clearly marking it as an example/test-only value. Alternatively, make it required so users must provide their own project ID explicitly.


37-54: Resource definitions are well-structured with appropriate documentation.

Both rate limit resources are correctly configured with model-appropriate attributes, and the ignore_rate_limit_warning flag is properly set. The comments effectively document the deletion behavior and how it's handled by the provider.

examples/rate_limit/README.md (4)

73-90: Clarify environment variable naming inconsistency.

The usage instructions reference OPENAI_ADMIN_API (line 79), but the provider configuration in main.tf comments mention OPENAI_ADMIN_KEY (line 14). This naming discrepancy could confuse users about which environment variable to set. Ensure consistency or clarify the relationship between these variables.


92-131: Example components are clear and demonstrate practical usage patterns.

The resource creation and data source examples are well-structured and show key concepts like conditional usage with count. Code blocks are syntactically correct and align with the actual configurations in main.tf and data_sources.tf.


175-208: Import instructions are comprehensive and well-documented.

The import section clearly explains the composite ID format, prerequisites, and provides practical examples with verification steps. The use cases are relevant, and the instructions would help users bring existing rate limits under Terraform management.


210-217: Clean up section appropriately documents final state.

The documentation clearly explains what happens during terraform destroy (archival and reset, not deletion), which aligns with the provider improvements mentioned in the PR objectives.

examples/fine_tuning/data/fine_tune_data_v4.jsonl (1)

1-12: JSONL training examples are well-formed and factually correct

Each line is valid JSON (one object per line), follows the expected messages schema for chat fine‑tuning (system/user/assistant roles), and the listed capitals for all countries are correct. This dataset looks ready to use as fine‑tuning input, assuming the file is stored as UTF‑8 to preserve the accented characters (e.g., “Brasília”).

examples/project_api/import_project_key.sh (1)

31-53: Input validation is clear and well-structured.

The argument and environment checks provide helpful error messages and graceful exits. Good defensive programming.

examples/project_api/main.tf (1)

1-113: Well-structured Terraform example with clear patterns.

The configuration demonstrates good practices:

  • Proper use of conditional data sources with count
  • Environment-based provider authentication
  • Clear output expressions with fallback messages for missing inputs
  • Good inline documentation
examples/vector_store/batch.tf (1)

1-23: LGTM!

The batch upload example correctly demonstrates the multi-file creation scenario described in the PR objectives. This pattern, combined with the retry logic in the provider, should handle eventual-consistency issues when creating multiple vector store files concurrently.

examples/vector_store/README.md (1)

1-144: Comprehensive and well-structured documentation.

The README clearly guides users through the vector store examples with prerequisites, configuration requirements, troubleshooting, and both module and direct resource approaches. The documentation correctly captures API constraints and error handling scenarios.

examples/vector_store/file.tf (1)

1-24: LGTM!

The file correctly demonstrates the vector store file creation pattern that benefits from the PR's retry logic. The openai_vector_store_file resource creation and immediate read is precisely the scenario the fix addresses (eventual-consistency handling when OpenAI API returns "file not found" temporarily).

examples/vector_store/outputs.tf (1)

1-35: LGTM!

The outputs are well-organized, providing both simple ID outputs and richer composite details. The aggregated all_vector_store_ids output offers a useful summary for users of these examples.

examples/vector_store/data_sources.tf (1)

1-97: Example file structure is well-organized.

The file provides comprehensive examples of querying vector store data sources with pagination, filtering, and nested resource relationships. The outputs effectively expose the key attributes users would need. The file complements the PR's fix for vector store file creation by demonstrating the subsequent data query operations users can perform after successful resource creation.

examples/messages/main.tf (4)

1-86: Solid setup for sample data generation.

The provider configuration, data directory creation, and sample file generation follow good Terraform practices with proper dependencies and path handling.


88-116: File uploads and thread creation are well-configured.

Proper sequencing with explicit dependencies and meaningful metadata usage.


158-179: Verify the module path reference.

The module reference at line 160 (source = "../../modules/messages") should be verified to ensure the module exists in the repository and exports the expected outputs (message_id, content, created_at, attachments).


182-244: Comprehensive and well-structured outputs.

The outputs provide useful information about created resources with clear descriptions and proper references to resource attributes.

examples/project_user/email_lookup.tf (1)

1-30: Well-structured email lookup pattern for project users.

The data source configuration and outputs clearly demonstrate how to retrieve project user information by email address, with proper dependencies and descriptive output names.

examples/organization_users/email_lookup.tf (1)

1-45: Clear demonstration of email-based organization user lookup.

The data sources and outputs effectively demonstrate how to retrieve organization user information by email address, with a practical commented example showing how to use the retrieved user ID in downstream resources.

examples/project_user/README.md (1)

334-366: Excellent guidance on role management and API integration.

The section on "Role Management and API Integration" (lines 334-366) provides valuable context about how Terraform handles configuration drift and role updates. This is particularly useful for users unfamiliar with how the provider handles the source-of-truth pattern.

examples/invite/main.tf (3)

50-62: Clarify lifecycle configuration intent.

Line 54 sets prevent_destroy = false, which disables protection against destruction. Given the comment above about preventing deletion of accepted invitations, verify this is intentional. Typically, you would either omit this line (defaulting to false) or set it to true to prevent accidental deletion.

The current configuration allows Terraform to destroy the invitation resource, which could be problematic for accepted invitations. Consider whether this is the intended behavior or if you meant to enable a different lifecycle rule.


1-96: Well-designed 3-step invitation workflow with good conditional logic.

The use of variables (count blocks at lines 39 and 85) to control workflow steps and the lifecycle ignore_changes to handle non-updatable fields demonstrates good Terraform patterns for multi-step processes. The workflow instructions output is particularly helpful.


146-192: Comprehensive workflow instructions with practical error handling.

The workflow_instructions output and the locals block for email-to-ID mapping provide clear guidance for users on executing the multi-step invitation workflow, including handling edge cases like deletion of accepted invitations.

examples/project_user/main.tf (2)

1-56: Solid project setup and user data source configuration.

The project creation, organization user retrieval, and locals for determining org owner status follow good patterns. The setup clearly demonstrates prerequisites and context.


88-132: Well-structured outputs with proper aggregation functions.

The outputs use appropriate functions to extract user IDs, owner IDs, and member IDs from the project users data source, providing useful verification information without exposing sensitive internal fields.

examples/organization_users/main.tf (1)

87-132: Output definitions are well-structured and properly conditional.

The outputs correctly guard access to data sources and provide sensible disabled placeholders when the feature is off. Good use of descriptions and conditional ternary operators.

examples/invite/data_sources.tf (2)

24-47: Data source definitions are correct and well-commented.

The conditional data sources properly use count and depends_on for clarity. The warning comment on line 34 about potential timeouts with large invite lists is helpful for users.


80-103: All-invitations outputs are well-structured with appropriate empty defaults.

The use of empty collections [] and {} as fallbacks is idiomatic and safe. Outputs correctly filter and map invite data.

examples/project_user/data_sources.tf (1)

56-122: Output definitions are clear and comprehensive.

All outputs correctly reference data sources and module attributes with appropriate descriptions. The filtering logic (e.g., selecting owners or members) is clear and maintainable.

examples/embeddings/main.tf (1)

76-76: Module outputs are correctly defined.

Both referenced outputs exist in the embeddings module:

  • embedding_id output is defined (line 145 in modules/embeddings/main.tf)
  • model_used output is defined (line 135 in modules/embeddings/main.tf)

The references on lines 76 and 81 of examples/embeddings/main.tf are valid and match the actual module outputs.

examples/embeddings/README.md (1)

87-93: The review comment is incorrect and should be disregarded.

The import command on line 90 correctly references openai_chat_completion.embedding_simulation because that is the actual resource type and name defined in modules/embeddings/main.tf:66. The embeddings module intentionally uses openai_chat_completion as a simulation resource, not the separate openai_embedding resource type. This is a deliberate design choice explained in the README's context about "simulated embeddings." The import example is accurate as written.

Likely an incorrect or invalid review comment.

examples/upload/training_data.jsonl (1)

1-5: LGTM!

The training data file is correctly formatted as JSONL with appropriate prompt-completion pairs for OpenAI fine-tuning examples.

examples/upload/README.md (1)

144-147: Both resource types are valid and registered in the provider.

Verification confirms that both openai_fine_tuned_model and openai_fine_tuning_job are valid, registered Terraform resources in the provider (lines 280-281 of internal/provider/provider.go). The README's use of openai_fine_tuned_model is not incorrect—it's a legitimate resource type with full CRUD support. The presence of openai_fine_tuning_job in main.tf does not make the README example wrong; these appear to be two distinct resources that may serve different purposes in the fine-tuning workflow. No changes required.

Likely an incorrect or invalid review comment.

examples/model_response/model_response_input_items_data_source.tf (1)

1-41: Intentionally commented example file serves its purpose.

The examples are well-structured and demonstrate idiomatic usage of the openai_model_response_input_items data source with clear output patterns. Using comments to show alternative usage patterns is appropriate for documentation files.

examples/model_response/model_response_data_source.tf (1)

1-44: Example file is well-structured and demonstrates correct data source usage.

Both examples correctly show how to retrieve model responses and extract usage information. The mix of active and commented examples provides helpful guidance for different use cases.

examples/model_response/main.tf (2)

26-34: Use of lookup() for output safety is good practice.

The outputs correctly use lookup() with a fallback value to safely access nested attributes:

lookup(openai_model_response.bedtime_story.output, "text", "No output available")

This prevents errors if the output attribute structure changes. This approach is appropriate.

Also applies to: 45-48, 59-62, 92-105


16-24: I'll help verify the attribute compatibility. Since terraform isn't available in the sandbox, let me search for information about the OpenAI Terraform provider schema and also check the repository for provider configuration.Now let me search more specifically for the mkdev-me provider documentation for the openai_model_response resource:

Let me search the repository to find the provider schema and resource definitions:

Based on my investigation, I cannot fully verify the attribute compatibility for the openai_model_response resource because:

  1. The openai_model_response resource exists in the mkdev-me/openai provider, but the Terraform Registry documentation requires JavaScript and is not accessible in this environment.

  2. The provider's GitHub repository is available, but the specific resource schema definitions are not accessible through web search.

  3. The terraform CLI is not available in the sandbox environment, so I cannot execute the validation command suggested in the review comment.

The original review comment's recommendation to run terraform validate is the correct approach. However, since this cannot be done in the current environment, the validation must be performed locally.


Verify attribute compatibility by running terraform validate locally.

The resource uses attributes including model, input, temperature, max_output_tokens, instructions, preserve_on_change, imported, and user. Execute terraform validate in your development environment to confirm these attribute names match the mkdev-me/openai provider's schema for the openai_model_response resource version in use.

examples/service_account/main.tf (1)

38-57: LGTM: Good use of defensive coding patterns.

The outputs properly use try() with fallback strings to handle permission errors gracefully. The sensitive = true flag on the API key output is good security practice, and the count conditional on the resource creation is a clean pattern.

examples/service_account/data_sources.tf (2)

36-50: LGTM: Data sources properly handle conditionals.

The data sources use appropriate count conditions and the depends_on sequencing ensures resources are created before data retrieval. The fallback local value pattern at lines 30-33 is clean and defensive.


65-88: LGTM: Outputs properly handle permission errors.

The outputs use try() with descriptive fallback values when permissions are insufficient, providing a good user experience when operations fail due to scope limitations.

examples/projects/main.tf (3)

18-53: Resource definitions are well-structured and demonstrate useful patterns.

The resources properly showcase basic creation (test), production scenario (production), and optional resources using count = 0. No structural issues identified.


1-15: Verify fjcorp/openai provider availability and credentials support.

The web search could not locate the "fjcorp/openai" provider in the Terraform registry or public GitHub repositories. While the environment variable names OPENAI_API_KEY and OPENAI_ADMIN_KEY are standard patterns used by other OpenAI providers, the specific provider you've referenced cannot be verified.

Confirm that:

  1. The provider source "fjcorp/openai" v1.0.0 exists and is accessible in your environment
  2. It actually supports the OPENAI_API_KEY and OPENAI_ADMIN_KEY environment variables as documented

If this is a private provider, ensure its documentation confirms these specific environment variable names are recognized.


23-28: Attributes verified as valid in fjcorp/openai provider.

All referenced attributes on openai_project are documented in the provider schema:

  • id (read-only)
  • name (required)
  • created_at (read-only)
  • status (read-only)

The outputs in lines 23–28 and 56–63 correctly access these exposed attributes.

examples/projects/data_sources.tf (2)

21-56: Well-structured outputs demonstrating good Terraform patterns.

The outputs effectively showcase various query patterns: accessing single resource attributes, counting collections, and extracting specific fields via for-loops. Good example-quality documentation through code.


5-7: I need to search for more specific information about the fjcorp/openai Terraform provider schema. Let me try a targeted search:

Provider namespace "fjcorp/openai" does not appear to exist in the Terraform Registry.

Extensive searches for the fjcorp/openai provider yielded no results. The Terraform Registry contains multiple OpenAI providers (mkdev-me/openai, jianyuan/openai, nventive/openai, antonbabenko/openai, vravind1/openai, skyscrapr/openai), but "fjcorp/openai" is not among them. Verify the correct provider source before referencing its data sources or fields.

examples/projects/README.md (2)

167-191: Technical details and troubleshooting sections provide useful guidance.

The sections covering technical implementation details and common troubleshooting scenarios are well-written and address likely user issues.


58-120: All documented attributes are correctly exposed by the openai_project and openai_projects data sources.

Verification confirms that all attributes documented in the README (project_id, name, status, created_at, usage_limits, max_monthly_dollars, max_parallel_requests, max_tokens) match the actual schema definitions in data_source_openai_project.go and data_source_openai_projects.go. The examples are accurate and complete.

examples/projects/test.tf (1)

1-14: Test file correctly references valid data source attributes.

The openai_projects data source schema confirms both the projects attribute (TypeList, computed) and the name field (TypeString, computed) exist within each project object. The test configuration properly accesses these attributes to retrieve project count and names via outputs.

examples/run/main.tf (2)

1-120: Good example structure.

This file demonstrates the correct pattern for avoiding "thread already has an active run" errors by using separate threads. The approach is cleaner than forcing sequential execution with depends_on. The code is well-commented and includes diverse examples (basic run, custom parameters, combined thread_run, and data sources).


22-22: The model name gpt-4-turbo-preview is valid and actively maintained by OpenAI as an alias that automatically points to the latest GPT-4 Turbo preview version. The example code is correct as written.

examples/run/backup/main_original.tf (1)

133-149: Module path is valid—concern does not apply.

The verification confirms that the modules/run directory exists at the repository root with the required Terraform files (main.tf, variables.tf, outputs.tf). The relative path ../../modules/run from examples/run/backup/main_original.tf correctly resolves to this module. The example will not fail due to a missing module.

Likely an incorrect or invalid review comment.

examples/run/main.tf.example (1)

97-113: Module path is valid—no action required.

The modules/run module exists in the repository and is correctly referenced via the relative path ../../modules/run from the example location. The example will resolve properly.

examples/run/cleanup_active_runs.sh (1)

26-28: No changes needed—API version is current.

The current OpenAI Assistants API version is v2, which matches the header value in the script. The code is correct as written.

Comment on lines 1 to 4
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What's the weather forecast for Chicago?"}, {"role": "assistant", "content": "I don't have access to current weather forecasts, but I can tell you about typical weather patterns in Chicago based on historical data for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Is it going to be sunny in San Francisco tomorrow?"}, {"role": "assistant", "content": "I don't have access to real-time weather predictions, but I can discuss typical weather patterns in San Francisco during this season."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What should I wear in Boston today?"}, {"role": "assistant", "content": "I don't have access to current weather data, but I can provide suggestions based on typical Boston weather patterns for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Will there be a storm in Florida this week?"}, {"role": "assistant", "content": "I don't have access to current forecast data, but I can provide information about typical storm patterns in Florida during this season."}]} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Fix inconsistent system message across all training examples.

The system message claims the assistant "provides accurate forecasts," but every assistant response explicitly declines to provide forecasts (e.g., "I don't have access to current weather forecasts"). This inconsistency creates a contradictory training signal that could confuse the fine-tuned model about its capabilities.

Consider updating the system message to align with the assistant's actual behavior:

-{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What's the weather forecast for Chicago?"}, {"role": "assistant", "content": "I don't have access to current weather forecasts, but I can tell you about typical weather patterns in Chicago based on historical data for this time of year."}]}
+{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "What's the weather forecast for Chicago?"}, {"role": "assistant", "content": "I don't have access to current weather forecasts, but I can tell you about typical weather patterns in Chicago based on historical data for this time of year."}]}
-{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Is it going to be sunny in San Francisco tomorrow?"}, {"role": "assistant", "content": "I don't have access to real-time weather predictions, but I can discuss typical weather patterns in San Francisco during this season."}]}
+{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "Is it going to be sunny in San Francisco tomorrow?"}, {"role": "assistant", "content": "I don't have access to real-time weather predictions, but I can discuss typical weather patterns in San Francisco during this season."}]}
-{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What should I wear in Boston today?"}, {"role": "assistant", "content": "I don't have access to current weather data, but I can provide suggestions based on typical Boston weather patterns for this time of year."}]}
+{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "What should I wear in Boston today?"}, {"role": "assistant", "content": "I don't have access to current weather data, but I can provide suggestions based on typical Boston weather patterns for this time of year."}]}
-{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Will there be a storm in Florida this week?"}, {"role": "assistant", "content": "I don't have access to current forecast data, but I can provide information about typical storm patterns in Florida during this season."}]}
+{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "Will there be a storm in Florida this week?"}, {"role": "assistant", "content": "I don't have access to current forecast data, but I can provide information about typical storm patterns in Florida during this season."}]}
📝 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
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What's the weather forecast for Chicago?"}, {"role": "assistant", "content": "I don't have access to current weather forecasts, but I can tell you about typical weather patterns in Chicago based on historical data for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Is it going to be sunny in San Francisco tomorrow?"}, {"role": "assistant", "content": "I don't have access to real-time weather predictions, but I can discuss typical weather patterns in San Francisco during this season."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "What should I wear in Boston today?"}, {"role": "assistant", "content": "I don't have access to current weather data, but I can provide suggestions based on typical Boston weather patterns for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides accurate forecasts."}, {"role": "user", "content": "Will there be a storm in Florida this week?"}, {"role": "assistant", "content": "I don't have access to current forecast data, but I can provide information about typical storm patterns in Florida during this season."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "What's the weather forecast for Chicago?"}, {"role": "assistant", "content": "I don't have access to current weather forecasts, but I can tell you about typical weather patterns in Chicago based on historical data for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "Is it going to be sunny in San Francisco tomorrow?"}, {"role": "assistant", "content": "I don't have access to real-time weather predictions, but I can discuss typical weather patterns in San Francisco during this season."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "What should I wear in Boston today?"}, {"role": "assistant", "content": "I don't have access to current weather data, but I can provide suggestions based on typical Boston weather patterns for this time of year."}]}
{"messages": [{"role": "system", "content": "You are a weather assistant that provides information about typical weather patterns based on historical data."}, {"role": "user", "content": "Will there be a storm in Florida this week?"}, {"role": "assistant", "content": "I don't have access to current forecast data, but I can provide information about typical storm patterns in Florida during this season."}]}
🤖 Prompt for AI Agents
In examples/fine_tuning/training_data/sample_validation.jsonl around lines 1 to
4, the system message ("You are a weather assistant that provides accurate
forecasts.") contradicts the assistant responses that explicitly say it cannot
access current forecasts; update the system message across all examples to
reflect the assistant's actual behavior (e.g., "You are a weather assistant that
provides information about typical or historical weather patterns and cannot
access real-time forecasts") so the instruction and assistant outputs are
consistent; ensure every JSONL entry uses the revised system message exactly and
re-run validation to confirm no remaining contradictions.

Comment on lines 1 to 7
terraform {
required_providers {
openai = {
source = "fjcorp/openai"
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify provider source and version constraints.

The provider source is specified as fjcorp/openai without version constraints. Consider adding explicit version constraints to ensure reproducible configurations across environments.

Apply this diff to add version constraints:

terraform {
  required_providers {
    openai = {
      source = "fjcorp/openai"
+     version = ">= 1.0, < 2.0"  # Adjust based on provider releases
    }
  }
}

Alternatively, verify the intended version strategy for this provider.


🏁 Script executed:

#!/bin/bash
# Verify provider exists and check available versions
curl -s https://registry.terraform.io/v1/providers/fjcorp/openai | jq '.provider'

Length of output: 4


🏁 Script executed:

#!/bin/bash
# Check the actual file content
cat examples/model_response/main.tf | head -20

Length of output: 540


🏁 Script executed:

#!/bin/bash
# Search for known OpenAI provider sources in Terraform registry
# Check common variations
curl -s https://registry.terraform.io/v1/providers/opentofu/openai 2>/dev/null | jq '.provider.namespace' 2>/dev/null || echo "Not found"
curl -s https://registry.terraform.io/v1/providers/hashicorp/random 2>/dev/null | jq '.provider.namespace' 2>/dev/null || echo "Checking structure"

Length of output: 9


🏁 Script executed:

#!/bin/bash
# Search the codebase for all provider references
rg -n "source\s*=" examples/ --type hcl || rg -n "source\s*=" examples/ --type tf

Length of output: 7010


🏁 Script executed:

#!/bin/bash
# Verify the correct provider source exists
curl -s https://registry.terraform.io/v1/providers/mkdev-me/openai | jq '.provider.namespace'

Length of output: 4


Update provider source to match codebase standard.

The provider source fjcorp/openai is outdated and inconsistent with the rest of the codebase. Replace it with mkdev-me/openai, which is used consistently across all other example files.

terraform {
  required_providers {
    openai = {
-     source = "fjcorp/openai"
+     source = "mkdev-me/openai"
    }
  }
}
📝 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
terraform {
required_providers {
openai = {
source = "fjcorp/openai"
}
}
}
terraform {
required_providers {
openai = {
source = "mkdev-me/openai"
}
}
}
🤖 Prompt for AI Agents
In examples/model_response/main.tf around lines 1 to 7, the Terraform provider
source is set to "fjcorp/openai" which is inconsistent with the codebase
standard; update the provider block to use "mkdev-me/openai" instead, ensuring
the required_providers entry's source value is replaced and the file matches
other example files.

To run these examples:

1. Set your OpenAI API key as an environment variable:
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifiers to fenced code blocks per MD040 rule.

The terraform validate command checks configuration syntax, and documentation should follow consistent markdown standards. Markdownlint requires language identifiers on code blocks for proper rendering and syntax highlighting.

Apply these diffs to add language specifiers:

-   ```
+   ```bash
    export OPENAI_API_KEY="your-api-key"
    ```
-   ```
+   ```bash
    terraform init
    ```
-   ```
+   ```bash
    terraform apply
    ```
-```
+```bash
 POST https://api.openai.com/v1/responses                  # Create a model response

Also applies to: 160-160, 165-165, 179-179

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

155-155: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In examples/model_response/README.md around lines 155, 160, 165, and 179,
several fenced code blocks are missing language specifiers; update each fenced
block to include the appropriate language tag (e.g., ```bash) before the code
and keep the closing ``` after it so markdownlint MD040 is satisfied —
specifically add ```bash for the export/openai key block (line ~155), the
terraform init block (~160), terraform apply block (~165), and the POST request
block (~179).

Below is an example workflow showing what happens when importing a moderation resource:

1. Original state before removal:
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifiers to fenced code blocks.

Several code blocks are missing language identifiers, which will cause linting failures. The static analysis tool (markdownlint) flags these violations:

  • Line 107: terraform state show output → use ```bash or ```shell
  • Line 128: terraform state rm command → use ```bash or ```shell
  • Line 135: terraform import command → use ```bash or ```shell
  • Line 146: Import confirmation output → use ```bash or ```shell
  • Line 180: Output structure → use ```text or ```plaintext
-   ```
+   ```bash
    $ terraform state show openai_moderation.harmful_text

Apply similar fixes to lines 128, 135, 146 (use bash or shell), and line 180 (use text or plaintext).

Also applies to: 128-128, 135-135, 146-146, 180-180

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

107-107: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In examples/moderation/README.md around lines 107, 128, 135, 146, and 180,
several fenced code blocks are missing language specifiers which triggers
markdownlint failures; update each opening triple-backtick to include the
appropriate language tag: use ```bash or ```shell for the command/CLI outputs on
lines 107, 128, 135, and 146, and use ```text or ```plaintext for the plain
output/example on line 180, ensuring each fenced block begins with the chosen
specifier and no other content is changed.

Comment on lines 68 to 74
# Only use organization data if enabled, otherwise skip
locals {
owners = var.enable_organization_users ? [
for user in data.openai_organization_users.all[0].users :
user if user.role == "owner" && user.id != data.openai_organization_user.specific[0].id
] : []
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix null reference in locals block when enable_organization_users is false.

Line 72 references data.openai_organization_user.specific[0].id inside the list comprehension, but when enable_organization_users is false, this data source does not exist. Terraform will fail at plan/apply time with "resource not found" error.

Apply this fix to guard the data source access:

 locals {
-  owners = var.enable_organization_users ? [
+  owners = (var.enable_organization_users && length(data.openai_organization_user.specific) > 0) ? [
     for user in data.openai_organization_users.all[0].users :
-    user if user.role == "owner" && user.id != data.openai_organization_user.specific[0].id
+    user if user.role == "owner" && user.id != try(data.openai_organization_user.specific[0].id, "")
   ] : []
 }

Alternatively, simplify by moving the filter logic inside a try() or using concat() to safely reference only when enabled.

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

🤖 Prompt for AI Agents
In examples/organization_users/main.tf around lines 68 to 74, the locals block
always evaluates references to data.openai_organization_user.specific[0].id even
when var.enable_organization_users is false, causing a "resource not found"
error; fix it by guarding the data source access (e.g., replace the direct
reference with a safe call using try(...) or a conditional expression so that
when enable_organization_users is false you return an empty list and when true
you compare user.id against try(data.openai_organization_user.specific[0].id,
null)); ensure the locals block never dereferences the data source when disabled
and keep the original owner filtering logic intact.

Comment on lines 45 to 97
# Show all vector stores in your account
output "vector_stores_list" {
value = data.openai_vector_stores.all.vector_stores
}

# Show detailed information about a specific vector store
output "vector_store_details" {
value = {
id = data.openai_vector_store.existing.id
name = data.openai_vector_store.existing.name
file_count = data.openai_vector_store.existing.file_count
status = data.openai_vector_store.existing.status
created_at = data.openai_vector_store.existing.created_at
file_ids = data.openai_vector_store.existing.file_ids
}
}

# Show list of files in a vector store
output "vector_store_files_list" {
value = data.openai_vector_store_files.store_files.files
}

# Show detailed information about a specific file in a vector store
output "vector_store_file_details" {
value = {
id = data.openai_vector_store_file.specific_file.id
created_at = data.openai_vector_store_file.specific_file.created_at
status = data.openai_vector_store_file.specific_file.status
attributes = data.openai_vector_store_file.specific_file.attributes
}
}

# Show file content from a vector store
output "vector_store_file_content" {
value = substr(data.openai_vector_store_file_content.file_content.content, 0, 100)
}

# Show detailed information about a file batch in a vector store
output "vector_store_file_batch_details" {
value = {
id = data.openai_vector_store_file_batch.specific_batch.id
created_at = data.openai_vector_store_file_batch.specific_batch.created_at
status = data.openai_vector_store_file_batch.specific_batch.status
file_ids = data.openai_vector_store_file_batch.specific_batch.file_ids
batch_type = data.openai_vector_store_file_batch.specific_batch.batch_type
purpose = data.openai_vector_store_file_batch.specific_batch.purpose
}
}

# Show list of files in a batch
output "vector_store_file_batch_files_list" {
value = data.openai_vector_store_file_batch_files.batch_files.files
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove trailing whitespace on line 97.

Line 97 has trailing whitespace after the closing brace.

-} 
+}
🤖 Prompt for AI Agents
In examples/vector_store/data_sources.tf around lines 45 to 97, there is
trailing whitespace at the end of line 97 (after the closing brace); remove the
trailing spaces on that line (or run the repo formatter) so the line ends
exactly with the '}' and no extra whitespace.

Comment on lines 11 to 13
```
Authorization: Bearer YOUR_API_KEY
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language identifier to fenced code block.

Line 11 uses a fenced code block without specifying a language. Add a language identifier (yaml, bash, etc.) for syntax highlighting and linting compliance.

-```
+```yaml
 Authorization: Bearer YOUR_API_KEY
-```
+```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In examples/vector_store/files/api_documentation.md around lines 11 to 13, the
fenced code block lacks a language identifier; update the opening fence to
include an appropriate language (e.g., "yaml" or "bash") so it reads as ```yaml
(or ```bash) followed by the existing content and the closing ``` to enable
syntax highlighting and satisfy linting.

Comment on lines 75 to 80
```
curl -X POST https://api.example.com/v1/workflows/trigger \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"workflow_id": "wf_123", "data": {"key": "value"}}'
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Sanitize example curl command to avoid security concerns.

Line 76-77 includes a curl example with an Authorization header containing a placeholder API key. While YOUR_API_KEY is a placeholder, Gitleaks flags this pattern as a potential security risk. Consider one of these approaches:

  1. Replace the placeholder with a comment:

    curl -X POST https://api.example.com/v1/workflows/trigger \
    -  -H "Authorization: Bearer YOUR_API_KEY" \
    +  -H "Authorization: Bearer <your-api-key-here>" \
       -H "Content-Type: application/json" \
       -d '{"workflow_id": "wf_123", "data": {"key": "value"}}'
  2. Or add an explicit security note:

    +**⚠️ Security note:** Never commit real API keys. Use environment variables or secret management tools.
🧰 Tools
🪛 Gitleaks (8.29.0)

[high] 76-77: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🤖 Prompt for AI Agents
In examples/vector_store/files/product_guide.md around lines 75 to 80, the curl
example includes an Authorization header with a literal placeholder API key
which Gitleaks flags; update the example to avoid exposing credential-like
patterns by either removing the header and showing a comment (e.g. replace the
header line with a comment like "# set Authorization header from environment"),
or replace the literal placeholder with a clearly non-secret token or
environment variable usage (e.g. show -H "Authorization: Bearer $API_KEY"), and
add a one-line security note stating readers must not paste real keys and should
use environment variables or secret management when running examples.

## API Questions

### What is the rate limit for API calls?
Free tier accounts are limited to 60 requests per minute. Standard tier accounts are limited to 600 requests per minute. Enterprise accounts have customizable rate limits based on their specific needs.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix compound modifier hyphenation.

Line 17 uses "tier accounts" where a hyphen is needed for the compound modifier.

-Free tier accounts are limited to 60 requests per minute. Standard tier accounts are limited to 600 requests per minute.
+Free tier-accounts are limited to 60 requests per minute. Standard tier-accounts are limited to 600 requests per minute.

Or consider rephrasing for clarity:

-Free tier accounts are limited to 60 requests per minute. Standard tier accounts are limited to 600 requests per minute.
+Accounts on the free tier are limited to 60 requests per minute. Standard tier accounts are limited to 600 requests per minute.
📝 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
Free tier accounts are limited to 60 requests per minute. Standard tier accounts are limited to 600 requests per minute. Enterprise accounts have customizable rate limits based on their specific needs.
Free-tier accounts are limited to 60 requests per minute. Standard-tier accounts are limited to 600 requests per minute. Enterprise accounts have customizable rate limits based on their specific needs.
🧰 Tools
🪛 LanguageTool

[grammar] ~17-~17: Use a hyphen to join words.
Context: ...ited to 60 requests per minute. Standard tier accounts are limited to 600 request...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In examples/vector_store/files/support_faq.md around line 17, the phrase "tier
accounts" is being used as a compound modifier and should be hyphenated; change
to "Free-tier accounts", "Standard-tier accounts", and "Enterprise-tier
accounts" (or alternatively rephrase to "Free accounts", "Standard accounts",
and "Enterprise accounts are limited to...") so the compound modifier is
correctly formed.

Comment on lines 1 to 66
terraform {
required_providers {
openai = {
source = "fjcorp/openai"
version = "1.0.0"
}
}
}

provider "openai" {}

# Example 1: Simple Vector Store without files
module "basic_vector_store" {
source = "../../modules/vector_store"

name = "Basic Knowledge Base"

# Add some metadata for organization
metadata = {
"category" = "general",
"purpose" = "demonstration",
"version" = "1.0"
}

}

# Example 2: Vector Store with individually added files
module "support_vector_store" {
source = "../../modules/vector_store"

name = "Support Knowledge Base"
file_ids = []

use_file_batches = true

file_attributes = {
"department" = "support",
"language" = "english"
}

}

# Example 3: Vector Store with file batches
module "api_vector_store" {
source = "../../modules/vector_store"

name = "API Documentation Store"
file_ids = []

use_file_batches = true

}

# Example 4: Create a resource directly (not through the module)
resource "openai_vector_store" "custom_store" {
name = "Custom Vector Store"

# Start without files, add them later
file_ids = []

metadata = {
"project" = "terraform-demo",
"owner" = "infrastructure-team"
}

}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify provider version availability.

The Terraform configuration specifies openai provider version 1.0.0. Ensure this version is available from the fjcorp/openai namespace in the Terraform Registry.


🌐 Web query:

Is Terraform provider fjcorp/openai version 1.0.0 available in the Terraform Registry?

💡 Result:

Short answer: No — there is no fjcorp/openai provider (v1.0.0) listed on the Terraform Registry. I found no registry entry for fjcorp/openai; the only third‑party OpenAI Terraform provider I could find listed publicly is e.g. jianyuan/openai. [1][2]

Sources:
[1] Search results showing Terraform OpenAI provider projects. (reddit.com)
[2] General web search results (no registry entry for fjcorp/openai). (gist.github.com)

Citations:



Replace the non-existent provider with a valid Terraform OpenAI provider.

The provider fjcorp/openai version 1.0.0 does not exist in the Terraform Registry. The only third-party OpenAI Terraform provider available is jianyuan/openai. Update lines 2-5 to use a valid provider, or implement a custom provider if required.

🤖 Prompt for AI Agents
In examples/vector_store/main.tf lines 1-66, the terraform required_providers
block references a non-existent provider "fjcorp/openai" version "1.0.0";
replace that with the valid third-party provider "jianyuan/openai" and set an
appropriate released version (for example a stable version constraint like ">=
0.5.0" or a specific released tag), update any provider configuration if the
jianyuan provider uses different argument names, then run terraform init to
fetch the correct provider and verify there are no schema mismatches.

@pabloinigo pabloinigo force-pushed the fix/issue-35-vector-store-file-read branch from 9bf8f9c to e100e7f Compare November 19, 2025 10:13
@pabloinigo pabloinigo force-pushed the fix/issue-35-vector-store-file-read branch from e100e7f to d28b7ec Compare November 19, 2025 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error creating openai_vector_store_file resources

3 participants