feat: add var to block custom component execution#11893
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughIntroduces a system-wide feature flag Changes
Sequence DiagramsequenceDiagram
participant Client as Client/UI
participant API as Backend API
participant Settings as Settings Service
participant Cache as Component Cache
participant Build as Build Engine
Client->>API: Request to execute flow
API->>Settings: get_settings_service()
Settings-->>API: allow_custom_components flag
alt allow_custom_components == false
API->>Cache: get all_types_dict
Cache-->>API: component registry
API->>API: check_flow_and_raise(flow, cache)
alt Custom components detected
API-->>Client: HTTP 400 (Validation Error)
else Valid components only
API->>Build: proceed with build
end
else allow_custom_components == true
API->>Build: skip validation, proceed
end
Build-->>API: build result
API-->>Client: response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Suggested labels
Suggested reviewers
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 2 warnings, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is ❌ Your project status has failed because the head coverage (49.06%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## release-1.9.0 #11893 +/- ##
=================================================
+ Coverage 49.14% 50.00% +0.85%
=================================================
Files 1928 1930 +2
Lines 171157 171890 +733
Branches 23730 24062 +332
=================================================
+ Hits 84123 85948 +1825
+ Misses 86007 84896 -1111
- Partials 1027 1046 +19
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json (1)
959-959:⚠️ Potential issue | 🟡 MinorTypo in README note: "coimponent" → "component".
Line 959 in the
note-RH5AHnode reads"the Tavily AI Search coimponent".✏️ Proposed fix
-"Add your **Tavily API Key** to the Tavily AI Search coimponent.\n \n## Using the Flow +"Add your **Tavily API Key** to the Tavily AI Search component.\n \n## Using the Flow🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Research` Agent.json at line 959, Fix the typo in the README string within the note-RH5AH node: change "Tavily AI Search coimponent" to "Tavily AI Search component" in the description value so the README reads correctly; locate the JSON entry for the note-RH5AH node and update the description field accordingly.src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx (1)
596-610:⚠️ Potential issue | 🟠 MajorStale
useMemodependency:canEditCode/allowCustomComponentsmissing.Line 499 conditionally renders the Code button based on
canEditCode(which depends onallowCustomComponents), but theuseMemodependency array at line 598 still listshasCodeonly. IfallowCustomComponentschanges at runtime, the memoized output won't update.Proposed fix
[ hasCode, + allowCustomComponents, nodeLength, hasToolMode, toolMode,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx` around lines 596 - 610, The memoized value for the toolbar is missing dependencies—add canEditCode and allowCustomComponents to the useMemo dependency array so the memo updates when code-editing permission changes; locate the useMemo call in nodeToolbarComponent (the array currently contains hasCode, nodeLength, ... frozen, handleSelectChange) and include canEditCode and/or allowCustomComponents (whichever drives the conditional Code button rendering) to ensure the Code button re-renders when permissions change.src/backend/base/langflow/api/v1/chat.py (2)
99-113:⚠️ Potential issue | 🟠 MajorValidate persisted flow data when
datais omitted inretrieve_vertices_orderWhen
datais not provided, this path builds from DB (Line 109) without runningcheck_flow_and_raiseon stored flow JSON. That leaves a bypass for the feature flag in this endpoint.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/api/v1/chat.py` around lines 99 - 113, The DB-path for retrieve_vertices_order bypasses validation: when data is falsy the code calls build_graph_from_db without running check_flow_and_raise, so persisted flow JSON can skip the allow_custom_components rule; after obtaining the graph from build_graph_from_db you must extract the raw flow JSON (or model_dump of the graph) and call check_flow_and_raise with the same args used for the other branch (allow_custom_components=settings_service.settings.allow_custom_components, all_types_dict=component_cache.all_types_dict) before proceeding, mirroring the validation done in the build_and_cache_graph_from_data branch.
654-687:⚠️ Potential issue | 🟠 MajorPublic build path still misses full validation coverage and status mapping
In
build_public_tmp, only requestdatais validated. Ifdatais absent, persisted public flow data is not checked. Also,ValueErrorfrom validation is currently wrapped as500by the broad handler instead of400.Suggested fix direction
async def build_public_tmp(...): try: # Validate custom components if blocking is enabled settings_service = get_settings_service() allow_custom = settings_service.settings.allow_custom_components if data: check_flow_and_raise( data.model_dump(), allow_custom_components=allow_custom, all_types_dict=component_cache.all_types_dict, ) # Verify this is a public flow and get the associated user client_id = request.cookies.get("client_id") owner_user, new_flow_id = await verify_public_flow_and_get_user(flow_id=flow_id, client_id=client_id) + + # Validate persisted flow data when request payload is not provided + if not data: + async with session_scope() as session: + flow = await session.get(Flow, flow_id) + if flow and flow.data: + check_flow_and_raise( + flow.data, + allow_custom_components=allow_custom, + all_types_dict=component_cache.all_types_dict, + ) # Start the flow build using the new flow ID job_id = await start_flow_build(...) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc except Exception as exc: await logger.aexception("Error building public flow") if isinstance(exc, HTTPException): raise raise HTTPException(status_code=500, detail=str(exc)) from exc🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/api/v1/chat.py` around lines 654 - 687, In build_public_tmp, if the incoming request data is missing you must validate the persisted public flow before building—after verify_public_flow_and_get_user (which returns owner_user and new_flow_id) load the persisted flow model/dict and call check_flow_and_raise with allow_custom_components and component_cache.all_types_dict to ensure full validation; also update the exception handler in build_public_tmp so a ValueError from validation is converted to an HTTPException with status_code=400 (i.e., if isinstance(exc, ValueError): raise HTTPException(status_code=400, detail=str(exc)) from exc) while preserving existing behavior for HTTPException and other exceptions when calling start_flow_build.
♻️ Duplicate comments (2)
src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (1)
1306-1306: Same PromptComponent helper-signature verification applies here.This embedded code mirrors the same
process_prompt_template(...)call pattern already flagged in the other starter project update.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Youtube` Analysis.json at line 1306, The three calls to process_prompt_template in PromptComponent (inside update_build_config, _update_template, and update_frontend_node) need the same helper-signature verification as in the other starter project: update each call to include the helper_signature/verification argument (or call the helper that validates the prompt helper signature) so process_prompt_template receives and verifies the helper signature before processing; adjust the calls in update_build_config (the try block), _update_template, and update_frontend_node to pass the helper signature parameter (or call the verified wrapper) and ensure validate_mustache_template remains intact.src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (1)
429-429: Same missingmodule_namepropagation appears in this embedded PromptComponentLine 429 has the same
process_prompt_template(...)call pattern withoutmodule_name; apply the same fix here to keep metadata/hash tracking consistent across starter projects.Based on learnings: In langflow custom components, the
module_nameparameter is now propagated through template building functions to add module metadata and code hashes to frontend nodes for better component tracking and debugging.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Basic` Prompting.json at line 429, The PromptComponent is calling process_prompt_template without passing module_name, so add module_name propagation to all process_prompt_template calls in this class (specifically in update_build_config, _update_template, and update_frontend_node) by passing module_name=self.module_name (or the correct component module identifier) so frontend nodes receive module metadata/hash tracking; ensure you add the same named kwarg in each call and keep existing try/except and validation logic unchanged.
🧹 Nitpick comments (8)
src/backend/base/langflow/initial_setup/setup.py (1)
82-83: Consider logging alias collisions to make fallback behavior observable.When
short_nameis already present, the alias is silently skipped. A debug log here would make failed rename reconciliation much easier to diagnose.Suggested tweak
- if short_name != key and short_name not in all_types_dict_flat: - all_types_dict_flat[short_name] = component + if short_name != key: + if short_name not in all_types_dict_flat: + all_types_dict_flat[short_name] = component + elif all_types_dict_flat[short_name] is not component: + logger.debug( + "Component alias collision for '%s' (module=%s); keeping existing mapping.", + short_name, + module, + )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/setup.py` around lines 82 - 83, When building alias map in setup.py the code silently skips adding an alias if short_name already exists (in the block checking short_name != key and short_name not in all_types_dict_flat). Add a debug-level log for the collision case so skip is observable: when short_name != key and short_name is already in all_types_dict_flat, emit a debug message including short_name, the existing entry (all_types_dict_flat[short_name]) and the new component so developers can see why the alias fallback happened; use the module logger (e.g., logging.getLogger(__name__) or the file's existing logger) and avoid changing control flow.src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (1)
1895-1895: Propagatemodule_nameinprocess_prompt_template(...)calls.Line 1895 updates template-processing logic, but the embedded
PromptComponentstill callsprocess_prompt_template(...)withoutmodule_name. Passing it will keep module/code-hash metadata propagation consistent for frontend node tracking.♻️ Proposed fix inside the embedded PromptComponent code
- _ = process_prompt_template( + _ = process_prompt_template( template=template_value, name="template", custom_fields=build_config["custom_fields"], frontend_node_template=build_config, is_mustache=is_mustache, + module_name=getattr(self, "module_name", self.__module__), )- _ = process_prompt_template( + _ = process_prompt_template( template=prompt_template, name="template", custom_fields=custom_fields, frontend_node_template=frontend_node_template, is_mustache=is_mustache, + module_name=getattr(self, "module_name", self.__module__), )- _ = process_prompt_template( + _ = process_prompt_template( template=template, name="template", custom_fields=frontend_node["custom_fields"], frontend_node_template=frontend_node["template"], is_mustache=is_mustache, + module_name=getattr(self, "module_name", self.__module__), )Based on learnings, In langflow custom components, the
module_nameparameter is now propagated through template building functions to add module metadata and code hashes to frontend nodes for better component tracking and debugging.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Twitter` Thread Generator.json at line 1895, The process_prompt_template(...) calls inside PromptComponent (in update_build_config, _update_template, and update_frontend_node) must include the new module_name parameter so module/code-hash metadata is propagated; update each call to pass a module_name value (e.g., module_name=self.__class__.__module__ or appropriate module identifier available in the method) alongside the existing args to ensure frontend node tracking gets the component module metadata.src/frontend/src/modals/codeAreaModal/index.tsx (1)
247-250: Redundant guard — AceEditorreadOnlyalready prevents edits.The
readOnly={readonly || isBlocked}on line 235 prevents the editor from producing change events. ThisonChangeguard is defense-in-depth, which is fine, but worth noting it's not strictly necessary.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/frontend/src/modals/codeAreaModal/index.tsx` around lines 247 - 250, The onChange handler contains a redundant guard around isBlocked because the AceEditor already sets readOnly={readonly || isBlocked} and will not emit editable changes; simplify by removing the defensive branch inside the onChange callback and directly call setCode(value) (or keep a single early return for clarity) in the onChange handler for the AceEditor component to reduce dead code; update references: the onChange prop, setCode function, isBlocked flag, and the readOnly prop on the AceEditor.src/frontend/src/stores/flowStore.ts (1)
913-917: Use a more stable custom-component-block detection signal.At Line 913, detection depends on one literal phrase in
list. If backend wording changes, or the signal is only intitle, the UI can wrongly show the outdated-components warning.Suggested fix
- const isCustomComponentBlocked = list.some( - (msg) => - msg.toLowerCase().includes("custom components are not allowed"), - ); + const errorText = [title, ...list].join(" ").toLowerCase(); + const isCustomComponentBlocked = errorText.includes( + "custom components are not allowed", + );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/frontend/src/stores/flowStore.ts` around lines 913 - 917, The current detection in isCustomComponentBlocked relies on the exact phrase "custom components are not allowed" in the list array and can miss signals in other fields or different wording; update the check used before referencing get().componentsToUpdate to inspect likely fields on each list item (e.g., title, message, detail) and match a more robust pattern (case-insensitive substring or small regex) that looks for tokens like "custom component" plus verbs like "not allowed|blocked|forbidden|unsupported", or better yet check for a backend-provided flag/name if present; modify the logic around isCustomComponentBlocked and the list traversal so it checks multiple properties per item and uses the looser matching rule to avoid false negatives.src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (2)
2498-2498: Consider excluding volatilescorefrom committed starter flow JSON.
scorevalues are typically runtime/editor-derived and can create unnecessary churn in PRs without functional impact.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting` Summary.json at line 2498, Remove the volatile "score" field from the committed starter flow JSON (e.g., in Meeting Summary.json) to avoid churn; either delete all "score" keys from the JSON file(s) or update the export/generation step that produces starter_projects to strip "score" before committing so runtime/editor-derived scores are not persisted.
537-537: Propagatemodule_namein template processing calls for metadata/code-hash traceability.The embedded
PromptComponentcode callsprocess_prompt_template(...)withoutmodule_namein multiple paths, which can weaken frontend node metadata consistency for template-derived fields.♻️ Proposed patch inside the embedded Prompt component code string
- _ = process_prompt_template( + _ = process_prompt_template( template=template_value, name="template", custom_fields=build_config["custom_fields"], frontend_node_template=build_config, + module_name=self.__class__.__module__, is_mustache=is_mustache, ) ... - _ = process_prompt_template( + _ = process_prompt_template( template=prompt_template, name="template", custom_fields=custom_fields, frontend_node_template=frontend_node_template, + module_name=self.__class__.__module__, is_mustache=is_mustache, ) ... - _ = process_prompt_template( + _ = process_prompt_template( template=template, name="template", custom_fields=frontend_node["custom_fields"], frontend_node_template=frontend_node["template"], + module_name=self.__class__.__module__, is_mustache=is_mustache, )Based on learnings: In langflow custom components, the
module_nameparameter is now propagated through template building functions to add module metadata and code hashes to frontend nodes for better component tracking and debugging.Also applies to: 1559-1559
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting` Summary.json at line 537, The three calls to process_prompt_template in update_build_config, _update_template, and update_frontend_node omit module_name, so add module_name when calling process_prompt_template to propagate component metadata; pass module_name=getattr(self, "module_name", self.__class__.__module__) (or self.__class__.__module__ directly) in each call (the calls are inside the functions update_build_config, _update_template, and update_frontend_node) so frontend_node/custom_fields get the module metadata and code-hash traceability.src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json (1)
1570-1570: Sanitize template-validation debug logs to avoid leaking user prompt content.The new debug paths interpolate
{e}from template validation failures. If exception messages include template fragments, logs may capture user-authored prompt text. Prefer logging a stable message (or exception type) without raw exception text.Also applies to: 1738-1738, 1909-1909
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Sequential` Tasks Agents.json at line 1570, The debug logs in update_build_config (logger.debug in the try/except), _update_template (logger.debug in its except), and update_frontend_node (logger.debug in its except) currently interpolate the exception message (f"...: {e}") which can leak user prompt content; change these to log a stable, non-sensitive message and include only the exception type/name (e.g., type(e).__name__) or a fixed tag instead of the raw exception text so logs do not contain user prompt fragments.src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json (1)
765-765: Propagatemodule_nameinprocess_prompt_template(...)callsLine 765’s embedded
PromptComponentprocesses template variables withoutmodule_name, so module/code-hash metadata propagation can be incomplete for generated frontend fields.♻️ Suggested patch inside the embedded PromptComponent code
- _ = process_prompt_template( + _ = process_prompt_template( template=template_value, name="template", custom_fields=build_config["custom_fields"], frontend_node_template=build_config, is_mustache=is_mustache, + module_name=self.__class__.__module__, ) ... - _ = process_prompt_template( + _ = process_prompt_template( template=prompt_template, name="template", custom_fields=custom_fields, frontend_node_template=frontend_node_template, is_mustache=is_mustache, + module_name=self.__class__.__module__, ) ... - _ = process_prompt_template( + _ = process_prompt_template( template=template, name="template", custom_fields=frontend_node["custom_fields"], frontend_node_template=frontend_node["template"], is_mustache=is_mustache, + module_name=self.__class__.__module__, )Based on learnings: In langflow custom components, the
module_nameparameter is now propagated through template building functions to add module metadata and code hashes to frontend nodes for better component tracking and debugging.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Custom` Component Generator.json at line 765, The PromptComponent calls to process_prompt_template (in update_build_config, _update_template, and update_frontend_node) need to include the module_name parameter so module/code-hash metadata is propagated; update each call to pass module_name (use self.module_name when present, otherwise fall back to self.__module__) into process_prompt_template, ensuring the same module_name value is supplied in all three locations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/backend/base/langflow/api/v1/chat.py`:
- Around line 99-105: The retrieval endpoints call check_flow_and_raise(...)
(e.g., inside retrieve_vertices_order) which raises ValueError on invalid flows
but bubbles up and becomes a 500; wrap the call to check_flow_and_raise in a
try/except that catches ValueError and raises
fastapi.HTTPException(status_code=400, detail=str(err)) so validation failures
return HTTP 400; apply the same pattern for the other similar block (lines
133-147) that performs check_flow_and_raise, referencing the same symbols
(retrieve_vertices_order, check_flow_and_raise,
settings_service.settings.allow_custom_components,
component_cache.all_types_dict) when adding the try/except and converting
ValueError -> HTTP 400.
- Around line 31-33: The import of check_flow_and_raise is pointing to a
non-existent module path (langflow.api.utils.flow_validation) and the import
block ordering violates Ruff rules; update the import to the correct module
where check_flow_and_raise is actually defined (replace the incorrect path with
the real module that exports check_flow_and_raise), then reorder the import
block so standard-library imports come first, third-party next, and
local/project imports last (ensure component_cache and schemas imports remain
together), and run Ruff/isort to validate formatting; reference the symbol
check_flow_and_raise in src/backend/base/langflow/api/v1/chat.py and adjust its
import and the surrounding import ordering accordingly.
In `@src/backend/base/langflow/api/v1/endpoints.py`:
- Around line 1047-1060: The update handler that instantiates
Component(_code=...) is missing the allow_custom_components guard; add the same
check used in the creation path: get settings_service and if
settings_service.settings.allow_custom_components is False, verify the supplied
code against known templates using component_cache.all_types_dict and
code_matches_any_template(raw_code.code, component_cache.all_types_dict), and if
not a known template raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
detail="Custom component creation is disabled by administrator"); apply this
logic in the /custom_component/update endpoint (the handler that constructs
Component) to prevent executing user code when custom components are disabled.
- Around line 453-463: The endpoint code calls check_flow_and_raise with
component_cache.all_types_dict without null checks; update each affected
endpoint (the blocks using component_cache.all_types_dict around where
check_flow_and_raise is invoked) to follow flows.py's defensive pattern: if
component_cache.all_types_dict is None, call await
get_and_cache_all_types_dict() and use its result (or assign back) before
passing all_types_dict into check_flow_and_raise; keep existing
get_settings_service() usage and preserve the HTTPException handling for
ValueError. Ensure you apply this same fix in all three locations that reference
component_cache.all_types_dict so the endpoints never pass None into
check_flow_and_raise.
In `@src/backend/base/langflow/initial_setup/starter_projects/Text` Sentiment
Analysis.json:
- Line 310: The code currently swallows ValueError from
validate_mustache_template in PromptComponent methods (update_build_config,
_update_template, update_frontend_node) which lets unsafe templates persist;
change each except block to fail-closed by re-raising the error (or raising a
new ValueError) after logging so the operation aborts and the invalid template
cannot be saved or used by build_prompt; locate the validate_mustache_template
calls inside update_build_config, _update_template, and update_frontend_node and
replace the current logger.debug-only except handlers with logic that logs then
raises the caught exception.
In `@src/backend/base/langflow/initial_setup/starter_projects/Travel` Planning
Agents.json:
- Line 913: The template.tools_metadata still references the old action name
"as_message" while the component output method was renamed to
fetch_content_as_message; locate the template.tools_metadata entry that maps
outputs/actions (look for the string "as_message" or the metadata keys tied to
the URLComponent outputs) and update it to use "fetch_content_as_message" (or
otherwise sync the method name to the Output with name "raw_results"/method
"fetch_content_as_message") so the metadata matches the actual method.
- Line 913: In fetch_url_contents, the per-URL exception handler (except
requests.exceptions.RequestException as e) always continues, ignoring the
continue_on_failure flag; change that handler to respect
self.continue_on_failure by logging the error as done now and if
self.continue_on_failure is True continue to next URL, otherwise raise a
ValueError (or re-raise) with a clear message (include the exception) so the
failure stops; update the except block inside fetch_url_contents to check
self.continue_on_failure and either continue or raise (use the same
logging/exception style as the outer except to keep consistency).
- Line 913: The component uses BeautifulSoup(..., "lxml") in the _text_extractor
method but lxml is not declared as an explicit dependency; update the component
metadata dependencies array (the JSON "dependencies" list for this starter
project) to include {"name": "lxml", "version": "<latest>"} so lxml is installed
explicitly alongside the existing dependency entries.
In
`@src/frontend/src/components/core/flowToolbarComponent/components/deploy-dropdown.tsx`:
- Around line 84-90: The onError handler in deploy-dropdown.tsx assigns a
possibly non-string detail (from e.response?.data?.detail) into setErrorData;
normalize that value to a string before putting it into list so UI/rendering
won't break. Update the onError block (the onError callback in this file) to
convert detail to a string (e.g., use typeof check and JSON.stringify fallback
or String(detail)) and pass that string to setErrorData({ title: "Failed to save
flow", list: [detailString] }). Ensure you reference the existing onError and
setErrorData symbols when making the change.
In
`@src/frontend/src/components/core/parameterRenderComponent/components/codeAreaComponent/index.tsx`:
- Around line 58-60: The local variable effectiveDisabled is computed but never
used, causing blocked state styling to not apply: update the render path to use
effectiveDisabled instead of the raw disabled prop (or remove effectiveDisabled
if you prefer Option A). Specifically, change calls to renderCodeText and
renderExternalLinkIcon (and any other places reading disabled) to pass or read
effectiveDisabled, and ensure isBlocked remains derived from useGetConfig() so
the lock icon and disabled classes reflect the combined blocked/prop state.
In `@src/frontend/src/hooks/flows/use-save-flow.ts`:
- Around line 108-113: The onError handler in use-save-flow.ts currently assigns
detail directly to list ([detail]) which can render objects/arrays as "[object
Object]"; normalize detail before calling setErrorData: detect if detail is an
array (Array.isArray) and set list to detail.map(String), if it's an object
convert to a readable array (e.g., Object.values(detail).flat().map(String) or
JSON.stringify(detail) as fallback), otherwise coerce to string; update the
onError block around the detail variable and the setErrorData call so
setErrorData({ title: "Failed to save flow", list: normalizedList }) always
receives an array of strings.
In `@src/frontend/src/stores/flowStore.ts`:
- Around line 764-778: The gate currently blocks builds when
get().componentsToUpdate has any entries, but componentsToUpdate is derived from
codeValidity.outdated and includes non-custom nodes; change the logic so the
block only triggers for components that are custom/user-edited (e.g., filter
get().componentsToUpdate for a property that marks custom edits such as
isCustom, userEdited, or origin === 'custom'), use that filtered list to build
outdatedNames, call setErrorData with that filtered list, and then call
get().setIsBuilding(false) and throw the Error as before; update the condition
that references allowCustomComponents and get().componentsToUpdate.length to
instead check the filteredCustomOutdated.length.
---
Outside diff comments:
In `@src/backend/base/langflow/api/v1/chat.py`:
- Around line 99-113: The DB-path for retrieve_vertices_order bypasses
validation: when data is falsy the code calls build_graph_from_db without
running check_flow_and_raise, so persisted flow JSON can skip the
allow_custom_components rule; after obtaining the graph from build_graph_from_db
you must extract the raw flow JSON (or model_dump of the graph) and call
check_flow_and_raise with the same args used for the other branch
(allow_custom_components=settings_service.settings.allow_custom_components,
all_types_dict=component_cache.all_types_dict) before proceeding, mirroring the
validation done in the build_and_cache_graph_from_data branch.
- Around line 654-687: In build_public_tmp, if the incoming request data is
missing you must validate the persisted public flow before building—after
verify_public_flow_and_get_user (which returns owner_user and new_flow_id) load
the persisted flow model/dict and call check_flow_and_raise with
allow_custom_components and component_cache.all_types_dict to ensure full
validation; also update the exception handler in build_public_tmp so a
ValueError from validation is converted to an HTTPException with status_code=400
(i.e., if isinstance(exc, ValueError): raise HTTPException(status_code=400,
detail=str(exc)) from exc) while preserving existing behavior for HTTPException
and other exceptions when calling start_flow_build.
In `@src/backend/base/langflow/initial_setup/starter_projects/Research`
Agent.json:
- Line 959: Fix the typo in the README string within the note-RH5AH node: change
"Tavily AI Search coimponent" to "Tavily AI Search component" in the description
value so the README reads correctly; locate the JSON entry for the note-RH5AH
node and update the description field accordingly.
In `@src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx`:
- Around line 596-610: The memoized value for the toolbar is missing
dependencies—add canEditCode and allowCustomComponents to the useMemo dependency
array so the memo updates when code-editing permission changes; locate the
useMemo call in nodeToolbarComponent (the array currently contains hasCode,
nodeLength, ... frozen, handleSelectChange) and include canEditCode and/or
allowCustomComponents (whichever drives the conditional Code button rendering)
to ensure the Code button re-renders when permissions change.
---
Duplicate comments:
In `@src/backend/base/langflow/initial_setup/starter_projects/Basic`
Prompting.json:
- Line 429: The PromptComponent is calling process_prompt_template without
passing module_name, so add module_name propagation to all
process_prompt_template calls in this class (specifically in
update_build_config, _update_template, and update_frontend_node) by passing
module_name=self.module_name (or the correct component module identifier) so
frontend nodes receive module metadata/hash tracking; ensure you add the same
named kwarg in each call and keep existing try/except and validation logic
unchanged.
In `@src/backend/base/langflow/initial_setup/starter_projects/Youtube`
Analysis.json:
- Line 1306: The three calls to process_prompt_template in PromptComponent
(inside update_build_config, _update_template, and update_frontend_node) need
the same helper-signature verification as in the other starter project: update
each call to include the helper_signature/verification argument (or call the
helper that validates the prompt helper signature) so process_prompt_template
receives and verifies the helper signature before processing; adjust the calls
in update_build_config (the try block), _update_template, and
update_frontend_node to pass the helper signature parameter (or call the
verified wrapper) and ensure validate_mustache_template remains intact.
---
Nitpick comments:
In `@src/backend/base/langflow/initial_setup/setup.py`:
- Around line 82-83: When building alias map in setup.py the code silently skips
adding an alias if short_name already exists (in the block checking short_name
!= key and short_name not in all_types_dict_flat). Add a debug-level log for the
collision case so skip is observable: when short_name != key and short_name is
already in all_types_dict_flat, emit a debug message including short_name, the
existing entry (all_types_dict_flat[short_name]) and the new component so
developers can see why the alias fallback happened; use the module logger (e.g.,
logging.getLogger(__name__) or the file's existing logger) and avoid changing
control flow.
In `@src/backend/base/langflow/initial_setup/starter_projects/Custom` Component
Generator.json:
- Line 765: The PromptComponent calls to process_prompt_template (in
update_build_config, _update_template, and update_frontend_node) need to include
the module_name parameter so module/code-hash metadata is propagated; update
each call to pass module_name (use self.module_name when present, otherwise fall
back to self.__module__) into process_prompt_template, ensuring the same
module_name value is supplied in all three locations.
In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting`
Summary.json:
- Line 2498: Remove the volatile "score" field from the committed starter flow
JSON (e.g., in Meeting Summary.json) to avoid churn; either delete all "score"
keys from the JSON file(s) or update the export/generation step that produces
starter_projects to strip "score" before committing so runtime/editor-derived
scores are not persisted.
- Line 537: The three calls to process_prompt_template in update_build_config,
_update_template, and update_frontend_node omit module_name, so add module_name
when calling process_prompt_template to propagate component metadata; pass
module_name=getattr(self, "module_name", self.__class__.__module__) (or
self.__class__.__module__ directly) in each call (the calls are inside the
functions update_build_config, _update_template, and update_frontend_node) so
frontend_node/custom_fields get the module metadata and code-hash traceability.
In `@src/backend/base/langflow/initial_setup/starter_projects/Sequential` Tasks
Agents.json:
- Line 1570: The debug logs in update_build_config (logger.debug in the
try/except), _update_template (logger.debug in its except), and
update_frontend_node (logger.debug in its except) currently interpolate the
exception message (f"...: {e}") which can leak user prompt content; change these
to log a stable, non-sensitive message and include only the exception type/name
(e.g., type(e).__name__) or a fixed tag instead of the raw exception text so
logs do not contain user prompt fragments.
In `@src/backend/base/langflow/initial_setup/starter_projects/Twitter` Thread
Generator.json:
- Line 1895: The process_prompt_template(...) calls inside PromptComponent (in
update_build_config, _update_template, and update_frontend_node) must include
the new module_name parameter so module/code-hash metadata is propagated; update
each call to pass a module_name value (e.g.,
module_name=self.__class__.__module__ or appropriate module identifier available
in the method) alongside the existing args to ensure frontend node tracking gets
the component module metadata.
In `@src/frontend/src/modals/codeAreaModal/index.tsx`:
- Around line 247-250: The onChange handler contains a redundant guard around
isBlocked because the AceEditor already sets readOnly={readonly || isBlocked}
and will not emit editable changes; simplify by removing the defensive branch
inside the onChange callback and directly call setCode(value) (or keep a single
early return for clarity) in the onChange handler for the AceEditor component to
reduce dead code; update references: the onChange prop, setCode function,
isBlocked flag, and the readOnly prop on the AceEditor.
In `@src/frontend/src/stores/flowStore.ts`:
- Around line 913-917: The current detection in isCustomComponentBlocked relies
on the exact phrase "custom components are not allowed" in the list array and
can miss signals in other fields or different wording; update the check used
before referencing get().componentsToUpdate to inspect likely fields on each
list item (e.g., title, message, detail) and match a more robust pattern
(case-insensitive substring or small regex) that looks for tokens like "custom
component" plus verbs like "not allowed|blocked|forbidden|unsupported", or
better yet check for a backend-provided flag/name if present; modify the logic
around isCustomComponentBlocked and the list traversal so it checks multiple
properties per item and uses the looser matching rule to avoid false negatives.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
src/frontend/package-lock.jsonis excluded by!**/package-lock.jsonuv.lockis excluded by!**/*.lock
📒 Files selected for processing (41)
src/backend/base/langflow/api/v1/chat.pysrc/backend/base/langflow/api/v1/endpoints.pysrc/backend/base/langflow/api/v1/projects.pysrc/backend/base/langflow/api/v1/schemas.pysrc/backend/base/langflow/initial_setup/setup.pysrc/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Blog Writer.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Document Q&A.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Research Agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.jsonsrc/frontend/src/CustomNodes/GenericNode/components/NodeUpdateComponent/index.tsxsrc/frontend/src/CustomNodes/GenericNode/index.tsxsrc/frontend/src/components/core/flowToolbarComponent/components/deploy-dropdown.tsxsrc/frontend/src/components/core/parameterRenderComponent/components/codeAreaComponent/index.tsxsrc/frontend/src/controllers/API/queries/config/use-get-config.tssrc/frontend/src/hooks/flows/use-save-flow.tssrc/frontend/src/modals/codeAreaModal/index.tsxsrc/frontend/src/pages/FlowPage/components/UpdateAllComponents/index.tsxsrc/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarFooterButtons.tsxsrc/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsxsrc/frontend/src/stores/flowStore.tssrc/frontend/src/stores/utilityStore.tssrc/frontend/src/types/zustand/utility/index.tssrc/frontend/src/utils/buildUtils.tssrc/frontend/src/utils/reactflowUtils.tssrc/lfx/src/lfx/services/settings/base.py
Add an environment variable (
LANGFLOW_ALLOW_CUSTOM_COMPONENTS) that allows users to run Langflow without allowing execution of custom code.Blocks all FE-related custom component creation and editing of components.
Will still allow you to upload flows with custom components, but will either prompt users with a notification to update, or a notification that it cannot run.
Allows users to specify a list of allowed components via the existing
LANGFLOW_COMPONENTS_PATH.Summary by CodeRabbit
New Features
Bug Fixes
Chores