Skip to content

fix(fx-core): recover from corrupted template metadata cache#16269

Open
neowenmsft wants to merge 2 commits into
OfficeDev:devfrom
neowenmsft:fix/cache-data-corruption
Open

fix(fx-core): recover from corrupted template metadata cache#16269
neowenmsft wants to merge 2 commits into
OfficeDev:devfrom
neowenmsft:fix/cache-data-corruption

Conversation

@neowenmsft

@neowenmsft neowenmsft commented Jul 2, 2026

Copy link
Copy Markdown

Summary

  • recover from corrupted ~/.fx/metadata/*.json reads by falling back to bundled metadata
  • recover from corrupted ~/.fx/ui/*.json reads by falling back to bundled UI nodes
  • clear version marker files when corruption is detected so metadata can be repopulated
  • add regression tests for corrupted cache recovery behavior

Validation

  • verified corrupted cache no longer crashes template listing in the fix branch
  • verified baseline behavior still reproduces JSON parse failure

Fixes #16245

Handle corrupted ~/.fx metadata and UI cache JSON by cleaning invalid cache entries and falling back to bundled metadata; add regression tests for recovery behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@neowenmsft

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="Microsoft"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates fx-core template metadata and UI-node loading to recover gracefully when cached JSON files under ~/.fx/** become corrupted, by invalidating the cache/version markers and falling back to the bundled metadata/UI shipped with the toolkit.

Changes:

  • Add best-effort cache invalidation that removes corrupted cache JSON plus relevant template version marker files so the cache can be repopulated.
  • Update cached UI-node loading (v3 channel) and cached template metadata loading to catch corruption and fall back to bundled assets.
  • Add regression tests covering corrupted-cache recovery scenarios (VSC/CLI and VS metadata; VSC UI nodes).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/fx-core/src/question/scaffold/vsc/rootNode.ts Recover from corrupted ~/.fx/ui/*.json by clearing cache/markers and falling back to bundled UI nodes.
packages/fx-core/src/component/generator/templates/metadata/index.ts Recover from corrupted ~/.fx/metadata/*.json / ~/.fx/vs-metadata/*.json by invalidating cache/markers and using bundled metadata.
packages/fx-core/tests/question/scaffold.test.ts Adds a regression test ensuring corrupted UI cache triggers marker clearing + bundled fallback.
packages/fx-core/tests/component/generator/templates/metadata.test.ts Adds regression tests for corrupted metadata cache recovery + marker clearing (VSC/VS).

Comment on lines +84 to +107
it("falls back to bundled metadata and clears cache markers when cached metadata is corrupted", () => {
sandbox.stub(templateHelper, "useLocalTemplate").returns(false);
sandbox.stub(folder, "getTemplatesFolder").returns(path.resolve("/bundled"));
sandbox.stub(fs, "pathExistsSync").returns(true);
const readFileSyncStub = sandbox.stub(fs, "readFileSync");
readFileSyncStub.onFirstCall().throws(new Error("corrupted cache"));
readFileSyncStub.onSecondCall().returns(JSON.stringify(mockTemplates));
const removeSyncStub = sandbox.stub(fs, "removeSync");

const result = getAllTemplatesOnPlatform(Platform.VSCode);

assert.deepEqual(result, [mockTemplates[0], mockTemplates[2]]);
assert.isTrue(removeSyncStub.called);
assert.isTrue(
removeSyncStub.calledWithMatch(
sinon.match((p) => String(p).includes("template-version.txt"))
)
);
assert.isTrue(
removeSyncStub.calledWithMatch(
sinon.match((p) => String(p).includes("template-version-v4.txt"))
)
);
});
Comment on lines +109 to +128
it("clears VS marker when VS cached metadata is corrupted", () => {
sandbox.stub(templateHelper, "useLocalTemplate").returns(false);
sandbox.stub(folder, "getTemplatesFolder").returns(path.resolve("/bundled"));
sandbox.stub(fs, "pathExistsSync").returns(true);
const readFileSyncStub = sandbox.stub(fs, "readFileSync");
readFileSyncStub.onFirstCall().throws(new Error("corrupted cache"));
readFileSyncStub.onSecondCall().returns(JSON.stringify(mockTemplates));
const removeSyncStub = sandbox.stub(fs, "removeSync");

const result = getAllTemplatesOnPlatform(Platform.VS);

assert.deepEqual(result, [mockTemplates[1]]);
assert.isTrue(
removeSyncStub.calledWithMatch(
sinon.match((p) =>
String(p).includes(path.join("vs-metadata", "template-vs-version.txt"))
)
)
);
});
Comment on lines +77 to +79
TOOLS?.logProvider?.info(
`[Dynamic Template] Cached ${fileName} is corrupted, fallback to bundled metadata.`
);
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.

bug report: Metadata can become corrupted and requires manual clearing

2 participants