Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(typescript/agent-os-vscode): validate Workflow shape on load before swapping in-memory state#2167

Merged
imran-siddique merged 1 commit into
microsoft:mainfrom
aegis-initiative:fix/typescript-workflow-designer-validate
May 12, 2026
Merged

fix(typescript/agent-os-vscode): validate Workflow shape on load before swapping in-memory state#2167
imran-siddique merged 1 commit into
microsoft:mainfrom
aegis-initiative:fix/typescript-workflow-designer-validate

Conversation

@finnoybu

Copy link
Copy Markdown
Contributor

Problem

WorkflowDesignerPanel._loadWorkflow accepted the result of an unchecked JSON.parse and wrote it straight into this._workflow:

if (uris && uris[0]) {
    const content = await vscode.workspace.fs.readFile(uris[0]);
    this._workflow = JSON.parse(content.toString());
    this._panel.webview.postMessage({ type: 'workflowLoaded', workflow: this._workflow });
}

Two failure modes silently passed through:

  1. Invalid JSONJSON.parse throws synchronously and the exception escapes _loadWorkflow into the unhandled-promise path. The webview is not told the load failed and the panel is left in a half-state.
  2. Wrong shape — any well-formed JSON object successfully replaced this._workflow with arbitrary shape (a truncated file, a hand-edited file with nodes removed, 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 / WorkflowEdge interfaces are declared in the same file, so the validator can mirror them directly without pulling in a schema-validation dependency.

Fix

  • Catch JSON.parse failures and surface them via vscode.window.showErrorMessage with the parse error, then return without touching this._workflow.
  • Add private static type guards _isWorkflow, _isWorkflowNode, _isWorkflowEdge that 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 (policy on nodes, label on edges) are only type-checked when present.
  • On a schema mismatch, surface a separate showErrorMessage describing the expected shape and return without mutating state. Only the success path replaces this._workflow and posts the workflowLoaded message to the webview.

The validator is intentionally shallow on node config (the existing Workflow interface declares it as Record<string, any>), which preserves backwards compatibility with workflow files containing tool-specific node configurations.

Test

The agent-os-vscode package's test script wraps the VS Code integration runner (node ./out/test/runTest.js) and the _loadWorkflow flow goes through vscode.window.showOpenDialog plus a webview postMessage; the existing test bed in src/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 as showErrorMessage rather than unhandled promise rejections.


Surfaced during independent audit conducted by @finnoybu (Ken Tannenbaum, AEGIS Initiative); [LOW, TypeScript].

`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.
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: code-reviewer — View details

TL;DR: 1 blocker, 0 warnings. The JSON parsing and validation logic needs to be improved to prevent potential security issues.

# Sev Issue Where
1 CRITICAL Unchecked JSON parsing can lead to unhandled promise rejections and incorrect workflow state agent-governance-typescript/agent-os-vscode/src/webviews/workflowDesigner/WorkflowDesignerPanel.ts

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.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: test-generator — `WorkflowDesignerPanel.ts`

WorkflowDesignerPanel.ts

  • test_invalid_json_handling -- Validate that invalid JSON triggers showErrorMessage and does not update this._workflow.
  • test_invalid_workflow_shape -- Validate that JSON with an incorrect schema triggers showErrorMessage and does not update this._workflow.
  • test_valid_workflow_load -- Ensure a valid workflow JSON updates this._workflow and posts the workflowLoaded message.
  • test_partial_node_validation -- Test that nodes with missing optional fields (e.g., policy) still pass validation.
  • test_partial_edge_validation -- Test that edges with missing optional fields (e.g., label) still pass validation.

@github-actions github-actions Bot added the size/M Medium PR (< 200 lines) label May 12, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: docs-sync-checker — Docs Sync

Docs Sync

  • WorkflowDesignerPanel._isWorkflow in WorkflowDesignerPanel.ts -- missing docstring
  • README.md -- section on workflow loading needs update
  • CHANGELOG.md -- missing entry for changes in workflow loading validation and error handling

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: security-scanner — Security Review

Security Review

Severity Finding Fix
LOW Potential Denial of Service (DoS) via unhandled promise rejection from invalid JSON input. Implement error handling for JSON.parse to catch exceptions and notify the user without mutating state.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: breaking-change-detector — API Compatibility

API Compatibility

Severity Change Impact
Potentially Breaking Introduced validation checks for the workflow structure and JSON parsing. If a user attempts to load a malformed workflow file, the application will now show an error message instead of silently failing, which may change the user experience.

@github-actions

Copy link
Copy Markdown

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential NONE
Overall MEDIUM

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label May 12, 2026
@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ❌ Failed Issues detected
🛡️ Security Scan ✅ Completed Analysis complete
🔄 Breaking Changes ✅ Completed Analysis complete
📝 Docs Sync ✅ Completed Analysis complete
🧪 Test Coverage ✅ Passed No issues found

Verdict: ❌ Changes needed

@imran-siddique imran-siddique merged commit 32eb05a into microsoft:main May 12, 2026
13 of 14 checks passed
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk size/M Medium PR (< 200 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants