Change:
this._welcomeMessage = new ChatWelcomeMessageModel(this, content); } <del> return requests.map((raw: ISerializableChatRequestData) => { const parsedRequest = typeof raw.message === 'string' ? this.getParsedRequestFromString(raw.message) : reviveParsedChatRequest(raw.message); const request = new ChatRequestModel(this, parsedRequest, raw.providerRequestId); if (raw.response || raw.responseErrorDetails) { const agent = raw.agent && this.chatAgentService.getAgents().find(a => a.id === raw.agent!.id); // TODO do something reasonable if this agent has disappeared since the last session request.response = new ChatResponseModel(raw.response ?? [new MarkdownString(raw.response)], this, agent, true, raw.isCanceled, raw.vote, raw.providerRequestId, raw.responseErrorDetails, raw.followups); } return request; }); </del> <ins> try { return requests.map((raw: ISerializableChatRequestData) => { const parsedRequest = typeof raw.message === 'string' ? this.getParsedRequestFromString(raw.message) : reviveParsedChatRequest(raw.message); const request = new ChatRequestModel(this, parsedRequest, raw.providerRequestId); if (raw.response || raw.responseErrorDetails) { const agent = raw.agent && this.chatAgentService.getAgents().find(a => a.id === raw.agent!.id); // TODO do something reasonable if this agent has disappeared since the last session request.response = new ChatResponseModel(raw.response ?? [new MarkdownString(raw.response)], this, agent, true, raw.isCanceled, raw.vote, raw.providerRequestId, raw.responseErrorDetails, raw.followups); } return request; }); } catch (error) { this.logService.error('Failed to parse chat data', error); return []; } </ins> } private getParsedRequestFromString(message: string): IParsedChatRequest { // TODO These offsets won't be used, but chat replies need to go through the parser as well <del> const parts = [new ChatRequestTextPart(new OffsetRange(1, message.length), { startColumn: 1, startLineNumber: 1, endColumn: 1, endLineNumber: 1 }, message)]; </del> <ins> const parts = [new ChatRequestTextPart(new OffsetRange(0, message.length), { startColumn: 1, startLineNumber: 1, endColumn: 1, endLineNumber: 1 }, message)]; </ins> return { text: message, parts

Discussion:
I guess this a regression from Have workspace setting like below Reload the window :bug: you get change in which is a spread of those compact settings <img width="1512" alt="Screenshot 2023-09-28 at 10 29 54" src=""
I actually thought this was intentional and have pushed the change to branch.
There should not be migration happening in this case right?
I would suggest to check the new value and write only if it is changed.
Sounds look. Looking into this atm.
Resolved the settings changing in scenarios where migration is not needed, but in scenarios where migration is needed, the above change still happens. Ends up looking like this: Digging into it further, this is because doesn't have the concept of anything outside of it's current scope (in this case, ), seems to find the setting multiple times for each language. Not sure if there is a better way to handle the migrations but would appreciate some thoughts/insight - some of the more complex examples in are still a tad different from what we want to accomplish here.
I think you are doing the right thing here. The scenario you are hitting here is a limitation with the api. This is true with all editor settings migrations so it is not new with your migration. I would recommend you to go with your change ie., do migration only when value has changed. Filed separate issue to fix this in the update method - - I would prefer to fix this in next milestone because 1. It is not a regression 2. It is not a simple fix to do and therefore risky to do in the endgame.
To confirm, even though value is migrated to each language independently, the effective value is correct and will be the migrated value. I mean, the value of for and languages will be
Yes - original override with is unchanged, but the new settings written are changed properly from boolean to respective enum.
closing and deferring rest of issue to
repro: setting is this: should end up like this without duplicating the settings: example with multiple: expected to turn into:
Found following bug while verifying -

In one of my workspaces I see no more chat. The console shows the stacktraces below, the debugger stops like this <img width="1302" alt="Screenshot 2023-09-28 at 10 26 44" src=""
omg, 1-indexed vs 0-indexed ranges... That is the fix, thanks for saving me from candidate shame
This would happen when a request body is empty. But probably the only way you would get in that state is if you had a session that was broken due to the issue that my original commit was fixing, which was broken chat session serialization. So I think the only way to verify it really is to check the window where you noticed the original issue. Or we can call it verified by code review.
verified by code review