Skip to content

Conversation

dieriba
Copy link
Contributor

@dieriba dieriba commented Oct 6, 2025

Important

This PR adds validation for retry configurations in both backend and frontend, ensuring exponential backoff seconds are positive integers, and refactors code to use this validation.

  • Backend:
    • Added validate_flow_value() in flows.rs to validate retry configurations and error handler muting.
    • Refactored create_flow() and update_flow() in flows.rs to use validate_flow_value().
  • Frontend:
    • Added validateRetryConfig() in utils.ts to validate retry configurations.
    • Integrated validateRetryConfig() in FlowBuilder.svelte and FlowRetries.svelte to validate retry settings before saving.
  • OpenAPI:
    • Updated Retry schema in openflow.openapi.yaml to enforce minimum value of 1 for exponential.seconds.

This description was created by Ellipsis for 723933c. You can customize this summary. It will automatically update as commits are pushed.

Copy link
Contributor

claude bot commented Oct 6, 2025

Claude finished @dieriba's task —— View job


Code Review: "nits: warning retry"

Todo List:

  • Read repository guidelines (CLAUDE.md)
  • Analyze backend changes (flows.rs)
  • Review frontend changes (FlowBuilder.svelte, FlowRetries.svelte)
  • Check utility changes (utils.ts)
  • Review OpenAPI specification changes
  • Provide comprehensive code review feedback
  • Include testing instructions

Review Summary

This PR enhances retry configuration validation in Windmill flows by adding both client-side and server-side validation for exponential backoff configurations. The changes prevent users from setting invalid retry parameters that could cause system issues.

Code Quality Assessment ✅

Backend Changes (flows.rs:88-118)

Strengths:

  • Proper validation logic for exponential backoff base seconds
  • Clear error messages explaining constraints
  • Consistent with existing validation patterns
  • Good defensive programming approach

Areas for Improvement:

  • Consider extracting magic numbers as constants:
    const MIN_EXPONENTIAL_BACKOFF_SECONDS: u64 = 1;

Frontend Changes

FlowBuilder.svelte (lines 432-439)

Excellent Implementation:

  • Validates retry configuration before deployment
  • Provides immediate feedback to users
  • Properly integrated into the existing save flow
  • Follows established error handling patterns

FlowRetries.svelte (lines 63-65, 260-268)

Well-designed validation:

  • Real-time validation with visual feedback (red border)
  • Clear error messaging with helpful explanations
  • Consistent with UI patterns throughout the codebase
  • Good UX for preventing invalid configurations

utils.ts (lines 1628-1636)

Solid utility function:

  • Consistent validation logic between frontend and backend
  • Proper type checking and bounds validation
  • Clear return type (string | null)
  • Good error message consistency

Security Implications ✅

  • No security concerns identified
  • Validation prevents potential DoS scenarios from immediate retries (seconds = 0)
  • Input sanitization is properly implemented

Performance Considerations ✅

  • Validation functions are lightweight
  • Client-side validation reduces unnecessary server requests
  • No performance impact on normal operations

Best Practices Adherence ✅

  • Clean Code: Functions are focused and well-named
  • No Duplication: Shared validation logic in utils.ts
  • Established Patterns: Follows existing validation patterns
  • Error Handling: Consistent error messaging across frontend/backend

Minor Issues

  1. backend/windmill-api/src/flows.rs:105-112

    • Consider extracting validation constants:
    const MIN_EXPONENTIAL_BACKOFF_SECONDS: u64 = 1;
  2. frontend/src/lib/components/flows/content/FlowRetries.svelte:266

    • Excellent user guidance text, very clear

Testing Instructions

To verify these retry validation changes:

  1. Access Flow Builder: Navigate to any flow in the Windmill interface and open the flow editor
  2. Configure Retry Settings: Select any flow module/step and go to the "Retries" tab in the settings panel
  3. Test Exponential Backoff Validation:
    • Choose "Exponential" retry type
    • Set the "Base (in seconds)" field to 0 or any negative number
    • Observe the red border validation and error message display
    • Try setting it to a valid value (≥1) and confirm the error clears
  4. Test Save Validation: With an invalid retry configuration (base = 0), attempt to deploy/save the flow and verify the deployment is blocked with a clear error message
  5. Test Valid Configuration: Set a valid retry configuration (base ≥ 1) and confirm the flow saves/deploys successfully

The validation should prevent invalid retry configurations both at the UI level (immediate feedback) and during deployment (server-side validation).


Comment on lines +108 to +112
if seconds == 0 {
return Err(Error::BadRequest(
"Exponential backoff base (seconds) must be greater than 0. A base of 0 would cause immediate retries.".to_string(),
));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The validation logic is inconsistent between the backend and frontend. The backend rejects only when seconds == 0, while the frontend validation and error message enforce seconds >= 1. To maintain consistency across the codebase:

  1. The backend check should be changed from if seconds == 0 to if seconds < 1
  2. The error message should match this logic

This would align with the frontend validation in validateRetryConfig() and the OpenAPI schema which specifies minimum: 1.

Suggested change
if seconds == 0 {
return Err(Error::BadRequest(
"Exponential backoff base (seconds) must be greater than 0. A base of 0 would cause immediate retries.".to_string(),
));
}
if seconds < 1 {
return Err(Error::BadRequest(
"Exponential backoff base (seconds) must be at least 1. A value less than 1 would cause too frequent retries.".to_string(),
));
}

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to 723933c in 2 minutes and 54 seconds. Click for details.
  • Reviewed 196 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. frontend/src/lib/utils.ts:1628
  • Draft comment:
    The validateRetryConfig function only checks the exponential.seconds property. Consider also validating other fields (like attempts or multiplier) if needed, or add documentation to clarify its intended scope.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% While the comment points out a potential enhancement, it's speculative - we don't know if those other fields actually need validation. The function may be intentionally focused only on seconds validation. Without seeing the Retry type definition and understanding the requirements, we can't be sure if validating other fields is necessary. The comment also hedges with "if needed", making it unclear if this is actually required. The comment could be valid if there are actual requirements to validate those other fields. I may be missing context about whether those validations are truly needed. However, the core rule is to only keep comments that are clearly correct and require action. This comment is speculative and depends on unknown requirements. If additional validation was needed, it likely would have been included in the initial implementation. Delete the comment since it makes speculative suggestions without clear evidence that the additional validation is actually required.
2. openflow.openapi.yaml:90
  • Draft comment:
    The addition of "minimum: 1" for exponential.seconds is correct and enforces the desired constraint in the API spec.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. backend/windmill-api/src/flows.rs:96
  • Draft comment:
    Typo suggestion: consider rephrasing this error message for clarity. Currently it reads "Muting the error handler for certain flow is only available in enterprise version". Perhaps revise to "Muting the error handler for a certain flow is only available in the enterprise version" or "... for certain flows ..." depending on the intended meaning.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While the comment suggests a valid grammatical improvement, it's a very minor change that doesn't significantly impact functionality or understanding. The current message is already clear enough. Making such minor text changes creates unnecessary churn and isn't worth the effort of a code change. The comment does point out a legitimate grammatical improvement. The current message could be slightly clearer. However, the current message is still perfectly understandable and the suggested change is extremely minor. We should focus PR comments on more substantive issues. Delete this comment as it suggests an extremely minor text change that isn't worth the effort of updating.

Workflow ID: wflow_aWh4bWkcueDHuNOO

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

for (const module of flow.value.modules) {
const error = validateRetryConfig(module.retry)
if (error) {
throw new Error(error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider including module identification (e.g. module id) in the error message when throwing an error from validateRetryConfig. This will help trace which module's retry config is invalid.

Suggested change
throw new Error(error)
throw new Error(`Module ${module.id}: ${error}`)

let result = $derived(
flowModule && flowStateStore?.val
? (flowStateStore.val[flowModule.id]?.previewResult ?? NEVER_TESTED_THIS_FAR)
: NEVER_TESTED_THIS_FAR
Copy link
Contributor

Choose a reason for hiding this comment

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

Good use of derived stores to show the validation error. Consider if similar validation is needed for the constant retry settings or adding comments to clarify why only the exponential section is validated.

const flow = cleanInputs(flowStore.val)
if (flow.value?.modules) {
for (const module of flow.value.modules) {
Copy link
Contributor

Choose a reason for hiding this comment

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

that only validate the first level, use dfs function to go through all the modules

));
}

if let Some(modules) = flow_value.get("modules").and_then(|m| m.as_array()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

it only go through first level, there is likely a dfs function somewhere however I think it might be the wrong approach, you likely want to try to deserialize each module and fail at first module that can't be deserializing with giving the id + error from the deserializer. Much more generic. You can then just apply a validate function on a FlowModuleValue directly for anything post validation.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants