fix(typescript/agent-os-vscode): validate Workflow shape on load before swapping in-memory state#2167
Merged
imran-siddique merged 1 commit intoMay 12, 2026
Conversation
`WorkflowDesignerPanel._loadWorkflow` was assigning the result of `JSON.parse(content.toString())` directly to `this._workflow` and posting it to the webview, with no validation that the parsed payload matched the local `Workflow` interface. A truncated, hand-edited, or unrelated `.json` file would silently replace the in-memory workflow with arbitrary shape, and the next save / simulate / postMessage call would dereference `.nodes`, `.edges`, or `.policies` on whatever was parsed — typically surfacing as an unhandled TypeError from the simulation runner rather than a useful diagnostic. Add structural validators (`_isWorkflow`, `_isWorkflowNode`, `_isWorkflowEdge`) that mirror the local interface declarations. Surface JSON-parse failures and schema mismatches as `showErrorMessage` so the user knows the file was rejected, and only swap `this._workflow` when validation passes.
🤖 AI Agent: code-reviewer — View detailsTL;DR: 1 blocker, 0 warnings. The JSON parsing and validation logic needs to be improved to prevent potential security issues.
Action items: Implement error handling for JSON parsing and validate the structure of the parsed workflow to ensure it matches expected types before mutating state. Warnings: No warnings found. Fine as follow-up PRs. |
🤖 AI Agent: test-generator — `WorkflowDesignerPanel.ts`
|
🤖 AI Agent: docs-sync-checker — Docs SyncDocs Sync
|
🤖 AI Agent: security-scanner — Security ReviewSecurity Review
|
🤖 AI Agent: breaking-change-detector — API CompatibilityAPI Compatibility
|
|
🟡 Contributor Check: MEDIUM
Automated check by AGT Contributor Check. |
PR Review Summary
Verdict: ❌ Changes needed |
MohammadHaroonAbuomar
pushed a commit
to MohammadHaroonAbuomar/agt-acs
that referenced
this pull request
Jun 1, 2026
…rosoft#2167) `WorkflowDesignerPanel._loadWorkflow` was assigning the result of `JSON.parse(content.toString())` directly to `this._workflow` and posting it to the webview, with no validation that the parsed payload matched the local `Workflow` interface. A truncated, hand-edited, or unrelated `.json` file would silently replace the in-memory workflow with arbitrary shape, and the next save / simulate / postMessage call would dereference `.nodes`, `.edges`, or `.policies` on whatever was parsed — typically surfacing as an unhandled TypeError from the simulation runner rather than a useful diagnostic. Add structural validators (`_isWorkflow`, `_isWorkflowNode`, `_isWorkflowEdge`) that mirror the local interface declarations. Surface JSON-parse failures and schema mismatches as `showErrorMessage` so the user knows the file was rejected, and only swap `this._workflow` when validation passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
WorkflowDesignerPanel._loadWorkflowaccepted the result of an uncheckedJSON.parseand wrote it straight intothis._workflow:Two failure modes silently passed through:
JSON.parsethrows synchronously and the exception escapes_loadWorkflowinto the unhandled-promise path. The webview is not told the load failed and the panel is left in a half-state.this._workflowwith arbitrary shape (a truncated file, a hand-edited file withnodesremoved, a generic settings JSON the user picked by mistake). The next save / simulate / postMessage call dereferences.nodes.find(...),.edges.forEach(...), or.policies.includes(...)on whatever was parsed and surfaces an unhelpful TypeError from_simulate.The
Workflow/WorkflowNode/WorkflowEdgeinterfaces are declared in the same file, so the validator can mirror them directly without pulling in a schema-validation dependency.Fix
JSON.parsefailures and surface them viavscode.window.showErrorMessagewith the parse error, then return without touchingthis._workflow._isWorkflow,_isWorkflowNode,_isWorkflowEdgethat check each field declared on the local interfaces (id / name / description / nodes[] / edges[] / policies[] for the workflow itself; id / type / label / position.x / position.y / config for nodes; id / source / target for edges). Optional fields (policyon nodes,labelon edges) are only type-checked when present.showErrorMessagedescribing the expected shape and return without mutating state. Only the success path replacesthis._workflowand posts theworkflowLoadedmessage to the webview.The validator is intentionally shallow on node
config(the existingWorkflowinterface declares it asRecord<string, any>), which preserves backwards compatibility with workflow files containing tool-specific node configurations.Test
The agent-os-vscode package's
testscript wraps the VS Code integration runner (node ./out/test/runTest.js) and the_loadWorkflowflow goes throughvscode.window.showOpenDialogplus a webviewpostMessage; the existing test bed insrc/test/does not cover the workflow designer. The change is shape-only on the success path — a well-formed Workflow file still loads identically — and the new failure paths surface asshowErrorMessagerather than unhandled promise rejections.Surfaced during independent audit conducted by @finnoybu (Ken Tannenbaum, AEGIS Initiative); [LOW, TypeScript].