GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — fix(forks): stop sync demanding config the source never had by mzxchandra · Pull Request #6766 · simstudioai/sim Conversation
Contributor
WhatWorkspace fork sync manufactured required re-pick rows the source never asked for, disabling Sync and suppressing the "Fully mapped" badge. Two independently-reported symptoms turned out to be two distinct root causes landing on the same line in Symptom A — an Agent block whose tools include Jira Get Issue, with Select Issue deliberately blank so the agent resolves it at runtime. The modal demanded a value. Symptom B — a Jira block on WhyCause A — a block-level
|
| Block | Field | Before | After | |
|---|---|---|---|---|
| Jira Write | projectId |
true | false | Cause B |
| Jira Read Pinned | issueKey |
true | true | control — still gates |
| Agent Blank | tools[0].issueKey |
true | false | Cause A+B |
| Agent Pinned | tools[0].issueKey |
true | false | Cause A only (sourceValue: ACME-999) |
| KB Blank Doc | documentSelector |
— | false | KB anchor |
| KB Pinned Doc | documentSelector |
— | true | KB anchor control |
Row count unchanged (7 → 7). Push and pull directions produce identical flags.
End-to-end through the UI, on a forked workspace:
documentSelector = doc_child → after sync the target block holds doc=doc_child.cred_jira_a → cred_jira_child, KB kb_parent → kb_child, blanks preserved.{"restored":1} with the undo consumed; unlink left parent: null.apps/sim/lib/workflows/tool-input/param-visibility.test.ts (new), dependent-field-noun.test.ts (new), plus 12 cases added to dependent-reconfigs.test.ts. Every behavioral case was verified to fail without the fix, not just pass with it.
Full apps/sim suite: 1,968 files / 26,289 tests passing. turbo run type-check clean across all 24 workspaces. check:api-validation passes.
The pre-landing review caught a real defect in the first commit, fixed in 3ca8d29:
isNonEmptyValue about rawSourceValue, which flattens every non-string to '' for the wire contract. A multi-select dependent stores an array, so a populated one reported blank and stopped gating. Reachable today via zoho-desk departmentIds. Now asks the raw value.paramId..every() over an empty array (vacuously true) now pins both shapes.Select ${title.toLowerCase()} rendered "Select select issue" for titles that already read as instructions. Extracted and tested; a bare "Select" title now falls back instead of rendering "Select " / "No found".Security specialist: no findings.
human_in_the_loop. Its notification subblock is also a tool-input, but its tools execute directly with no model, so a user-or-llm blank there genuinely is missing. This change stops fork sync gating on it. The gap already exists in the editor — the HITL tool row shows no asterisk and saves blank — so fork sync was only masking it, and only for forked workspaces. The fix is editor-side (give those params explicit visibility: 'user-only', which re-gates them through this same rule). Separate PR.condition gating (sibling in-flight PR). It shrinks the blast radius but does not fix Cause B — write / read-bulk / get_project legitimately show the selector. Independent; can land in either order.The toggle-to-manual workaround persists advanced into those workflows, which changes which member serializes. Harmless while both fields are empty, but if anyone later picks a project in the basic selector it will be silently dropped. Not auto-migrated — those blocks want toggling back by hand.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Fork sync manufactured required re-pick rows the source never asked for, disabling
Sync and suppressing the "Fully mapped" badge. Two distinct causes landed on the
same line in `collectForkDependentReconfigs`.
Cause A - a block-level `required` applied to a nested tool param. The collector
runs one helper over both a block's own subblocks and the params of each tool in a
`tool-input`, reading the raw block config for the nested pass. A Jira Get Issue
tool inside an Agent block therefore inherited Jira's `issueKey` required-condition
even though the tool param is `visibility: 'user-or-llm'` - the agent fills it at
runtime, and `createLLMToolSchema` keeps an empty one in the model's schema
precisely so it can. The tool-row editor already strips `required` for anything not
`user-only`; the fork collector was the only surface that did not.
Cause B - demanding a value the source never had. `projectId` hangs off the
credential anchor, so a Jira block on `write` with a blank project emitted a
required row. The proof it is a collector bug: only members carrying a
`selectorKey` are emitted, so the basic selector gated while its advanced twin
(identical `required`, no `selectorKey`) did not - the same empty config blocked or
not purely on a display preference. That is also why toggling to manual mode
"fixed" it.
Neither fix subsumes the other: an emptiness guard alone leaves a *populated*
`user-or-llm` param gating after a parent swap (`effectiveDependentValue` blanks it
when the parent changed), and the visibility rule alone never touches top-level
subblocks.
Both invariants now meet in one predicate, and the tool-row rule is extracted so
the editor and the sync gate cannot drift. Rows are still emitted either way - only
the gating flag changes - so no stored dependent value is orphaned.
Also fixes the placeholder stutter in the re-pick selector ("Select select issue"),
which composed a verb onto titles that already read as instructions.
Verified end-to-end against a forked workspace: before, 3 of 7 rows were required
(including one with a populated source value); after, only a top-level populated
required field gates, Sync enables, and the badge reads "Fully mapped".
…e-required-blockers
… one Pre-landing review caught a silent un-gating in the new predicate: it asked `isNonEmptyValue` about `rawSourceValue`, which flattens every non-string to `''` for the wire contract. A multi-select dependent selector stores an array, so a populated one reported blank and stopped gating the sync. `isNonEmptyValue` handles arrays and non-strings deliberately - give it the raw value. Reachable today via zoho-desk `departmentIds`, the one multi-select dependent selector with a `selectorKey` + `dependsOn`. Also from review: - the canonical id is an alias, so it no longer clobbers a param that owns that key as its own `paramId` (first write wins) - drop a redundant conjunct that implied a third state the code cannot reach - document the present-but-undefined visibility case, which the resolver's `buildToolInputSearchConfig` branch produces routinely - extract the placeholder-noun transform so a bare "Select" title falls back to the whole title instead of rendering "Select " / "No found", and test it Tests: non-string and empty-array source values, both verified to fail without the fix; the basic/advanced parity case now pins both shapes rather than calling `.every()` on an empty array; the indexer mock is reset per test so the new cases are not order-dependent.
There was an error while loading. Please reload this page.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
PR SummaryMedium Risk Overview Gating rules — Pre-sync dependent reconfig rows still appear for in-place re-picks, but Post-sync promote — Cleared nested tool dependents use the same visibility map from UI copy — Dependent field selectors strip leading “Select/Choose/Pick” from titles before building placeholders, avoiding strings like “Select select issue”. Reviewed by Cursor Bugbot for commit dbeba09. Bugbot is set up for automated code reviews on this repo. Configure here. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Greptile SummaryThe PR fixes fork synchronization so blank source configuration and model-supplied tool parameters do not incorrectly block synchronization or redeployment.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| apps/sim/lib/workflows/tool-input/param-visibility.ts | Introduces shared visibility-aware requiredness helpers used consistently by editor and fork-sync paths. |
| apps/sim/ee/workspace-forking/lib/mapping/dependent-reconfigs.ts | Makes blank source dependents non-gating and applies authoritative tool-parameter visibility during pre-sync collection. |
| apps/sim/ee/workspace-forking/lib/remap/remap-references.ts | Applies the shared visibility rule to cleared nested tool parameters so promotion does not incorrectly suppress redeployment. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/sub-block-renderer.tsx | Reuses the shared user-supplied predicate to keep editor optionality aligned with fork synchronization. |
| apps/sim/ee/workspace-forking/components/fork-sync/dependent-field-selector.tsx | Uses normalized field nouns to avoid duplicated imperative wording in selector copy. |
| apps/sim/ee/workspace-forking/lib/mapping/dependent-reconfigs.test.ts | Adds broad regression coverage and converts the previously flagged declaration documentation to TSDoc. |
| apps/sim/ee/workspace-forking/lib/remap/remap-references.test.ts | Verifies that cleared model-supplied parameters remain surfaced without blocking redeployment. |
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Source[Source workflow configuration] --> PreSync[Collect dependent reconfigurations]
Visibility[Resolved parameter visibility] --> PreSync
PreSync --> Gate{User-required and source configured?}
Gate -->|Yes| Require[Require reconfiguration]
Gate -->|No| Allow[Allow synchronization]
Allow --> Merge[Merge and remap workflow]
Merge --> Cleared[Collect cleared target dependents]
Visibility --> Cleared
Cleared --> DeployGate{Required cleared value?}
DeployGate -->|Yes| Withhold[Withhold redeployment]
DeployGate -->|No| Redeploy[Redeploy synchronized workflow]
Reviews (2): Last reviewed commit: "style(forks): use TSDoc for the new test..." | Re-trigger Greptile
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Greptile caught a real asymmetry, and corrected a wrong assumption in the first commit: `needsConfiguration` is NOT warning-only. `promote.ts:1035` skips the target's redeploy for any workflow in that list, and `:792` also withholds its chat-deployment carry-over. So with only the pre-sync collector fixed, an Agent block whose Jira `issueKey` was populated in the target and cleared by a credential remap would let the sync through (the modal correctly treats a model-supplied param as non-blocking) and then silently decline to redeploy that workflow - leaving the fork running its previous deployed version with no gate and no error. Both collectors now resolve `required` through one shared `resolveToolParamRequired`, so the pre-sync gate and the promote path cannot disagree about what a nested tool param means. The lookup (sub-block id, then canonical param id, then fail closed to the block-level rule) lives in one place instead of being duplicated. The `@/tools/params` mock in remap-references.test.ts is now overridable so a test can opt into an authoritative resolution; its defaults are unchanged and the other 74 tests pass untouched. The new case is verified to fail without the fix.
CLAUDE.md requires TSDoc for documentation and no non-TSDoc comments. The vi.mock boundary note, the resolve helper, and the beforeEach mock-reset rationale all document declarations, so doc tooling could not associate them. In-body step comments are left as-is - they explain a flow, not a declaration.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@cursor review |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dbeba09. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
dbeba09e
Deployed
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.