If I change the casing of a filename in vscode on macOS, the old file name casing is forever stored in ~/Library/Application Support/Code/workspaceStorage, this causes problems with extensions that require case-sensitive file paths
Steps to Reproduce:

~/Library/Application Support/Code/workspaceStorageThis has come up when using the haxe language extension – after changing a file's case, the old file case given by vscode is sent to the haxe compiler, breaking autocomplete for this file (haxe nightly build 4.2)
Does this issue occur when all extensions are disabled?: Technically Yes (but it's probably not an issue without extensions)
@haxiomic isn't it enough to close the file and open it again? Having a hard time to understand how the casing of the file is persisted even when you close the file. What storage key do you still see the old casing persist?
@bpasero closing the file and opening has no affect, I’ve also tried
The extension still receives the original incorrect name
The problem is original name is always kept somewhere inside the workspaceStorage folder, I assume whatever checks are used when updating this state ignore file name casing so it never changes. The only workaround I’ve found is to delete this folder manually
@haxiomic without knowing the exact storage key that the extension is trying to access it is hard to understand the issue. It is possible that maybe the extension stores the URI?
Looks to be in codelens/cache2
I ran through the repro steps, renaming EXAMPLE.hx to Example.hx and in state.vscdb, the name is Example.hx everywhere except codelens/cache2:
{
"file:///Users/geo/Downloads/haxe-name-bug/EXAMPLE.hx": {
"lineCount": 9,
"lines": []
}
}
I don't know a lot about codelens at this point but this is the jsonrpc object pass in the vshaxe extension for autocomplete:
{
"jsonrpc": "2.0",
"id": 17,
"method": "display/completion",
"params": {
"file": "/Users/geo/Downloads/haxe-name-bug/EXAMPLE.hx",
"contents": "class Example {\n\n\tstatic var x:Int;\n\n\tstatic public function main() {\nxx\n\t}\n\n}",
"offset": 72,
"wasAutoTriggered": false,
"meta": [":deprecated"]
}
}
Thanks for finding out about the key.
This doesn't make sense. The codelens/cache2 cache is to persist info about where code lenses have been so that you don't see flicker after restarts or when changing files. However, is doesn't define the path of the model so it cannot be cause such issues.
Looks like the editor input serialised and restores the wrong uri

I cannot reproduce an issue here. My steps are the following:
super.tssuper.ts because it uses the text model URIsuper.ts to SUPER.tssuper.tsTo get out of this you will have to:
I am thinking this just works as designed and is a consequence of all the work we did to fix https://github.com/microsoft/vscode/issues/12448
@jrieken
Looks like the editor input serialised and restores the wrong uri
Well, not sure I would agree? You store canonical URIs in memory, so when the editor input gets created, even when the user changed the URI, the input will get your canonical form. I will store and restore only this form because for the editor input that is the only correct URI.
Has nothing to do with code lens. Do the following
vscode.workspace.onDidOpenTextDocument(d => console.log(d.uri.toString()))sample.txt in an editor, notice how its path is logged to the consolesAMple.txt, the editor title updates, keep the editor openYes, we have defined a canonical URI but not so that it survives a reload of the window/process. The form on disk should be the actual form and it seems that the serialised editor input defines the "wrong" canonical uri here.
File editor inputs now keep track of their preferredResource. This is the resource that was originally used by clients when wanting to create an input but it might be different from the resource given our canonical form. However, when the file editor input is being recreated from storage, it will use preferredResource and thus has a chance of being created with the "correct" URI.
This still requires a restart of VSCode but you no longer have to close the editor to get the "correct" URI.
Cannot do this, I see data loss when the file is dirty:
Very tricky, not having a good solution for now. The truth is that backup identifiers are the hash of a file path, so when an editor opens and gets dirty, the backup is a hash of its file path (preserving the casing). When the file is renamed, the hash does not change because we no longer change the underlying model, we just change the label.
If we now simply go ahead and change the model URI on restart because we pick the preferred URI now, the backup can no longer be found and the data is lost. Somehow the backup service would also need to be aware of a preferred URI vs initial URI.
The workaround for now is as I stated before:
Would it make sense to validate the persisted URI before making it the canonical one? Maybe not the whole path but just the basename?
@jrieken can you clarify what that would mean?
When restoring an editor input from a case-insensitive file system, check for its actual casing before proceeding to open.
Unfortunately there is no straightforward solution to know what casing a file has on disk other than doing readdir for each folder segment of a path and then using the name that is returned to build up the path.
node.js recently added fs.realpath.native but from my knowledge, this e.g. would convert a Windows subst path to its real path from C: drive, which is not really what we want.
And even if we decide to figure out the real path as it is on disk and then proceeding to create a model with that path, backups would still be stored under the previous case and fail to be looked up.
I think it is not impossible to fix this, e.g. we have a method to iterate over all backups and could then use the proper IURIIdentityService.extUri to compare for a backup instead of relying on the strict equalness. But since I leave on vac soon, I would only do this change when I am back.
Bottom line: I think the backup service should take the OS path case into account when answering the question wether a backup exists for a resource or not.
We closed this issue because we don't plan to address it in the foreseeable future. You can find more detailed information about our decision-making process here. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.
If you wonder what we are up to, please see our roadmap and issue reporting guidelines.
Thanks for your understanding and happy coding!
Most helpful comment
Very tricky, not having a good solution for now. The truth is that backup identifiers are the hash of a file path, so when an editor opens and gets dirty, the backup is a hash of its file path (preserving the casing). When the file is renamed, the hash does not change because we no longer change the underlying model, we just change the label.
If we now simply go ahead and change the model URI on restart because we pick the preferred URI now, the backup can no longer be found and the data is lost. Somehow the backup service would also need to be aware of a preferred URI vs initial URI.
The workaround for now is as I stated before: