You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot copy variable value when it's bigger than a certain length #5778
Describe the bug
When debugging, if I have a local variable of String type in the Variables window and its value is bigger than a certain length, the debugger will show it truncated with ellipsis and hitting Ctrl + C or right-clicking > Copy Value will only copy the shown value (truncated).
There's currently no alternative that I know of:
Using the debug console won't work for accessing private fields of other classes (and maybe would show the value truncated anway? Not sure)
Hovering over the variable in the editor also shows the value truncated;
There's no configuration option in launch.json for type:dart that I know of that controls this (apparently some other languages has an option for configuring this).
To Reproduce
Steps to reproduce the behavior:
Create a String local with a big length (eg > 1500 characters)
Start debugging (type: dart, request: launch)
Use the Variables window to inspect your variable
Expected behavior
I can copy the full value
Screenshots
Please complete the following information:
You can run the Dart: Collect Diagnostic Information command from the VS Code command palette (F1) to easily capture this information or provide it manually.
Operating System and version: Windows 11 Pro 25H2
VS Code version: win 1.105.1
Dart extension version: 3.122.0
Dart/Flutter SDK version: 3.8.0/3.32.0
Target device (if the issue relates to Flutter debugging): Windows
As a workaround while the maintained doesn't answer, when debugging, you can write the variable/expression on the debug console (there is a field below it for you to write things).
When you press enter/return it should display the whole variable in the console for you. I don't believe the console has a limit on length for this but maybe is something you can try to see if it helps.
It should work just fine if you are within that file that defines it. Maybe try adding a breakpoint inside it to test. I should've been clearer, sorry.
I'm not able to reproduce this - while the value is truncated in the tooltip (which is expected), "Copy Value" does copy the full value in my tests. For example in the code:
void main() {
var a = A();
print(a.a); // Breakpoint here
}
class A {
var a = '1234567890' * 100;
}
Hey, sure. You're correct that it not always reproduces. More info below.
First, here's the minimal repro:
dart create dartdebugstringlengthbug
dartdebugstringlengthbug.dart
import'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart';
final foo =Foo();
voidmain(List<String> arguments) {
print(foo.foo);
}
lib/dartdebugstringlengthbug.dart
classFoo {
final foo ="123"*1000;
}
If you break on print, F10 to instantiate foo, go to Globals window, inspect foo and Copy Value the field, it'll copy truncated.
Apparently there are few edge cases. I did some more tests after your reply:
The above code does not repro if you change final foo = Foo() to be a local or a field instead of a global.
The above code does repro if you change final foo = "123" * 1000; to be private, independently of whether final foo = Foo() is a local or global or a field in another class (sample code below)
@DanTup Thank you! Btw, I just noticed the conditions I specified may be more specific than necessary. If I've got my notes straight, the only thing you need is having a private field in a class that's in another file. Ignore this. The first repro I sent does not use private fields and still repros.
@andre-ss6 when I repro'd your first sample, I put it all in the same file too. I'll have to do some debugging to figure out exactly what's up, but my guess is that once fixed for one of your samples, it'll solve it for all of them. I'll post back once I get chance to look properly though. Thank you for the debugging and the test cases!
From my debugging, the issue affected child-variables of anything in "Globals", because we did not correctly pass down the expression to evaluate them (the way "Copy Value" and "Copy as Expression" work in VS Code is by re-evaluating a string expression to get the value).
If you see a similar issue for anything that is not a child-variable of a Global, please let me know.
The change is in the debug adapter which ships in the SDK, so after it's merged, it will take a Dart/Flutter SDK update to get the fix unfortunately (it won't show up in a Dart-Code update).
@andre-ss6 can you confirm the precise steps for the second repro? I tried what I think you meant, but it seems to work there for me (I'm expanding this in Locals and accessing it there):
@DanTup That's weird. It's just the steps I provided (ie, that code + debug and break on line 10, try to copy the value from the Locals Window), and at least from the screenshot seems like exactly what you're doing. I tried removing each variable/difference from our tests -- I was testing on Windows, switched to Mac; changed package name to be different to the file and class names, like in your case -- still, all repro'd the bug.
I'm attaching a screen recording as it may be easier to see what I'm doing/if we're doing anything differently:
Also here's a new recording showing how it doesn't repro when switching from _foo to foo (and I later switch back to _foo in the video to confirm that's the cause).
@andre-ss6 is it possible you could capture a log for me?
Start the app and get to the breakpoint
Open the command palette (F1)
Start the Dart: Capture Debugging Logs command
Reproduce the issue where copying fails - please also try right-clicking on the item to see whether the "Copy as Expression" entry appears (as this should be tied to the same functionality as untruncating)
Once you've copied, click Cancel on the logging notification to stop logging and open the log
Provide the log here (be sure to repro in this small sample since the log will contain parts of your workspace code)
(one thing to also check is whether Cmd+C and right-click -> Copy Value are doing different things?)
Reproduce the issue where copying fails - please also try right-clicking on the item to see whether the "Copy as Expression" entry appears (as this should be tied to the same functionality as untruncating)
(one thing to also check is whether Cmd+C and right-click -> Copy Value are doing different things?)
Copy expression does show up and cmd+c and right click both do the same thing. I show that in the first video (sorry for the a bit long recording, I know 😅 Less used to mac shortcuts + things always go wrong when recording 😅).
Anyway, the log below does seem to have the answer as to what's going on! I just don't understand why it didn't repro for you though 🤔
Log
!! ⚠️ PLEASE REVIEW THIS LOG FOR SENSITIVE INFORMATION BEFORE SHARING ⚠️ !!
Dart Code extension: 3.122.0
Flutter extension: 3.122.0 (not activated)
App: Visual Studio Code
App Host: desktop
Version: mac 1.105.1
Wed Nov 05 2025 [13:25:22 GMT-0300 (Brasilia Standard Time)] Log file started
[1:25:22 PM] [DAP] [Info] ==> {"command":"updateSendLogsToClient","arguments":{"enabled":true},"type":"request","seq":17}
[1:25:22 PM] [DAP] [Info] <== {"seq":29,"type":"response","command":"updateSendLogsToClient","request_seq":17,"success":true}
[1:25:25 PM] [DAP] [Info] ==> {"command":"evaluate","arguments":{"expression":"this.foo._foo","frameId":1,"context":"clipboard","format":{"hex":false}},"type":"request","seq":18}
[1:25:25 PM] [DAP] [Info] <== {"seq":30,"type":"event","body":{"message":"==> [VM] {"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}"},"event":"dart.log"}
[1:25:25 PM] [VmService] [Info] [Dart] ==> [VM] {"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}
[1:25:25 PM] [DAP] [Info] <== {"seq":31,"type":"event","body":{"message":"<== [VM] {"jsonrpc":"2.0","error":{"code":113,"message":"Expression compilation error","data":{"details":"org-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request":{"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}}},"id":"32"}"},"event":"dart.log"}
[1:25:25 PM] [DAP] [Info] <== {"seq":32,"type":"response","body":{"error":{"format":"{message}","id":1,"variables":{"message":"evaluateInFrame: (113) Expression compilation error\norg-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","stack":"#0 DartDebugAdapter.evaluateRequest (package:dds/src/dap/adapters/dart.dart:1142:7)\n\n#1 BaseDebugAdapter.handle (package:dds/src/dap/base_debug_adapter.dart:141:7)\n\n"}}},"command":"evaluate","message":"evaluateInFrame: (113) Expression compilation error\norg-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request_seq":18,"success":false}
[1:25:25 PM] [VmService] [Info] [Dart] <== [VM] {"jsonrpc":"2.0","error":{"code":113,"message":"Expression compilation error","data":{"details":"org-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request":{"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}}},"id":"32"}
Wed Nov 05 2025 [13:25:27 GMT-0300 (Brasilia Standard Time)] Log file ended
Thanks! This does indeed make sense now - it's failing to evaluate the private member from an expression, and therefore falling back to the truncated string it already had:
org-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.
- 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.
this.foo._foo
^^^^
There were some changes in the area of expression evaluation recently - I wonder if the new code supports evaluating the private field and old code did not - I will do some testing.
Both will arrive in a future Dart/Flutter SDK release.
There might still be cases where things don't work (because expression eval is always more restricted than just navigating across the types, but VS Code requires us to use an evaluated expression to copy the full version of a truncated value to the clipboard), we'll just have to file issues and look at them on a case-by-case basis to see whether they can be fixed.
Activity
FMorschel commentedon Oct 31, 2025
As a workaround while the maintained doesn't answer, when debugging, you can write the variable/expression on the debug console (there is a field below it for you to write things).
When you press enter/return it should display the whole variable in the console for you. I don't believe the console has a limit on length for this but maybe is something you can try to see if it helps.
artdedeco commentedon Oct 31, 2025
@FMorschel thanks for the suggestion, but I addressed that in the OP:
FMorschel commentedon Oct 31, 2025
It should work just fine if you are within that file that defines it. Maybe try adding a breakpoint inside it to test. I should've been clearer, sorry.
DanTup commentedon Oct 31, 2025
I'm not able to reproduce this - while the value is truncated in the tooltip (which is expected), "Copy Value" does copy the full value in my tests. For example in the code:
And copying here:
I get this in my clipboard:
@andre-ss6 are you able to provide a small code sample that definitely triggers this issue for you that I could test with?
This has been an issue in the past and I looked up the fix to see if it might be more recent than your SDK, but it was quite a while ago back in 2023:
dart-lang/sdk@5929460
Thanks!
artdedeco commentedon Oct 31, 2025
@DanTup
Hey, sure. You're correct that it not always reproduces. More info below.
First, here's the minimal repro:
dart create dartdebugstringlengthbugdartdebugstringlengthbug.dartlib/dartdebugstringlengthbug.dartIf you break on
print, F10 to instantiatefoo, go to Globals window, inspect foo and Copy Value the field, it'll copy truncated.Apparently there are few edge cases. I did some more tests after your reply:
final foo = Foo()to be a local or a field instead of a global.final foo = "123" * 1000;to be private, independently of whetherfinal foo = Foo()is a local or global or a field in another class (sample code below)Also repros:
dartdebugstringlengthbug.dartlib/dartdebugstringlengthbug.dartDanTup commentedon Oct 31, 2025
@andre-ss6 perfect, thank you! I can repro at least some of these and will look into fixing.
artdedeco commentedon Oct 31, 2025
@DanTup Thank you!
Btw, I just noticed the conditions I specified may be more specific than necessary. If I've got my notes straight, the only thing you need is having a private field in a class that's in another file.Ignore this. The first repro I sent does not use private fields and still repros.DanTup commentedon Oct 31, 2025
@andre-ss6 when I repro'd your first sample, I put it all in the same file too. I'll have to do some debugging to figure out exactly what's up, but my guess is that once fixed for one of your samples, it'll solve it for all of them. I'll post back once I get chance to look properly though. Thank you for the debugging and the test cases!
DanTup commentedon Nov 4, 2025
I've a fix open at https://dart-review.googlesource.com/c/sdk/+/459560
From my debugging, the issue affected child-variables of anything in "Globals", because we did not correctly pass down the expression to evaluate them (the way "Copy Value" and "Copy as Expression" work in VS Code is by re-evaluating a string expression to get the value).
If you see a similar issue for anything that is not a child-variable of a Global, please let me know.
The change is in the debug adapter which ships in the SDK, so after it's merged, it will take a Dart/Flutter SDK update to get the fix unfortunately (it won't show up in a Dart-Code update).
artdedeco commentedon Nov 4, 2025
Thanks @DanTup.
I'm not sure of what technically constitutes a Global in the lang spec, but informally seems like there's no globals in my second sample here.
DanTup commentedon Nov 4, 2025
@andre-ss6 sorry, I should've been clearer. I meant inspecting things inside the "Globals" section in the "Variables" panel of the debug sidebar.
artdedeco commentedon Nov 4, 2025
Ah, sure. In that case, yes, that second sample repros using the Locals window as well.
DanTup commentedon Nov 5, 2025
@andre-ss6 can you confirm the precise steps for the second repro? I tried what I think you meant, but it seems to work there for me (I'm expanding
thisin Locals and accessing it there):artdedeco commentedon Nov 5, 2025
@DanTup That's weird. It's just the steps I provided (ie, that code + debug and break on line 10, try to copy the value from the Locals Window), and at least from the screenshot seems like exactly what you're doing. I tried removing each variable/difference from our tests -- I was testing on Windows, switched to Mac; changed package name to be different to the file and class names, like in your case -- still, all repro'd the bug.
I'm attaching a screen recording as it may be easier to see what I'm doing/if we're doing anything differently:
dart-issue.mov
artdedeco commentedon Nov 5, 2025
Also here's a new recording showing how it doesn't repro when switching from
_footofoo(and I later switch back to_fooin the video to confirm that's the cause).dart-issue2.mov
DanTup commentedon Nov 5, 2025
@andre-ss6 is it possible you could capture a log for me?
F1)(one thing to also check is whether Cmd+C and right-click -> Copy Value are doing different things?)
artdedeco commentedon Nov 5, 2025
@DanTup Sure! I'm attaching the logs below.
Copy expression does show up and cmd+c and right click both do the same thing. I show that in the first video (sorry for the a bit long recording, I know 😅 Less used to mac shortcuts + things always go wrong when recording 😅).
Anyway, the log below does seem to have the answer as to what's going on! I just don't understand why it didn't repro for you though 🤔
Log
!!⚠️ PLEASE REVIEW THIS LOG FOR SENSITIVE INFORMATION BEFORE SHARING ⚠️ !!
Dart Code extension: 3.122.0
Flutter extension: 3.122.0 (not activated)
App: Visual Studio Code
App Host: desktop
Version: mac 1.105.1
Workspace type: Dart (LSP)
Workspace name: dartdebugstringlengthbug
Dart (3.9.2): /Users/andre/source/flutter/bin/cache/dart-sdk
Flutter (3.35.7): /Users/andre/source/flutter (No device)
Logging Categories:
General, AnalyzerTiming, CommandProcesses, DartTest, DartToolingDaemon, DAP, VmService, DevTools, FlutterDaemon, FlutterRun, FlutterTest, FlutterWidgetPreview, WebDaemon
Wed Nov 05 2025 [13:25:22 GMT-0300 (Brasilia Standard Time)] Log file started
[1:25:22 PM] [DAP] [Info] ==> {"command":"updateSendLogsToClient","arguments":{"enabled":true},"type":"request","seq":17}
[1:25:22 PM] [DAP] [Info] <== {"seq":29,"type":"response","command":"updateSendLogsToClient","request_seq":17,"success":true}
[1:25:25 PM] [DAP] [Info] ==> {"command":"evaluate","arguments":{"expression":"this.foo._foo","frameId":1,"context":"clipboard","format":{"hex":false}},"type":"request","seq":18}
[1:25:25 PM] [DAP] [Info] <== {"seq":30,"type":"event","body":{"message":"==> [VM] {"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}"},"event":"dart.log"}
[1:25:25 PM] [VmService] [Info] [Dart] ==> [VM] {"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}
[1:25:25 PM] [DAP] [Info] <== {"seq":31,"type":"event","body":{"message":"<== [VM] {"jsonrpc":"2.0","error":{"code":113,"message":"Expression compilation error","data":{"details":"org-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request":{"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}}},"id":"32"}"},"event":"dart.log"}
[1:25:25 PM] [DAP] [Info] <== {"seq":32,"type":"response","body":{"error":{"format":"{message}","id":1,"variables":{"message":"evaluateInFrame: (113) Expression compilation error\norg-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","stack":"#0 DartDebugAdapter.evaluateRequest (package:dds/src/dap/adapters/dart.dart:1142:7)\n\n#1 BaseDebugAdapter.handle (package:dds/src/dap/base_debug_adapter.dart:141:7)\n\n"}}},"command":"evaluate","message":"evaluateInFrame: (113) Expression compilation error\norg-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request_seq":18,"success":false}
[1:25:25 PM] [VmService] [Info] [Dart] <== [VM] {"jsonrpc":"2.0","error":{"code":113,"message":"Expression compilation error","data":{"details":"org-dartlang-debug:synthetic_debug_expression:1:10: Error: The getter '_foo' isn't defined for the type 'Foo'.\n - 'Foo' is from 'package:dartdebugstringlengthbug/dartdebugstringlengthbug.dart' ('lib/dartdebugstringlengthbug.dart').\nTry correcting the name to the name of an existing getter, or defining a getter or field named '_foo'.\nthis.foo._foo\n ^^^^","request":{"jsonrpc":"2.0","id":"32","method":"evaluateInFrame","params":{"isolateId":"isolates/8616239353089527","frameIndex":0,"expression":"this.foo._foo","disableBreakpoints":true,"idZoneId":"zones/1"}}}},"id":"32"}
Wed Nov 05 2025 [13:25:27 GMT-0300 (Brasilia Standard Time)] Log file ended
DanTup commentedon Nov 5, 2025
Thanks! This does indeed make sense now - it's failing to evaluate the private member from an expression, and therefore falling back to the truncated string it already had:
There were some changes in the area of expression evaluation recently - I wonder if the new code supports evaluating the private field and old code did not - I will do some testing.
DanTup commentedon Nov 5, 2025
Yep, that's it - if I switch to the current stable then it fails like it does for you. On latest code, it works.
I found this CL:
dart-lang/sdk@1f845d1
So there were two issues here:
Both will arrive in a future Dart/Flutter SDK release.
There might still be cases where things don't work (because expression eval is always more restricted than just navigating across the types, but VS Code requires us to use an evaluated expression to copy the full version of a truncated value to the clipboard), we'll just have to file issues and look at them on a case-by-case basis to see whether they can be fixed.
Thanks for your help tracking these two down!
artdedeco commentedon Nov 5, 2025
Alrighty, sounds good. Thank you for following it up so quickly!
[dds/dap] Fix evaluateNames of global variables
DanTup commentedon Nov 24, 2025
The fix for the remaining issue landed in dart-lang/sdk@4f1f82f
The change is in the SDK, so will arrive in a future SDK release.