Skip to content

[tool_crash] Unhandled RangeError in CompactReporter._progressLine / truncate when terminal width is narrow #194569

Open

Description

@bkonyi

Summary

flutter test crashes with an unhandled RangeError in truncate (package:test_core/src/util/pretty_print.dart:65) called from CompactReporter._progressLine (package:test_core/src/runner/reporter/compact.dart:445) when stdout.terminalColumns (lineLength) is narrow enough that lineLength - length < 4.

Crash Telemetry (Flutter stable/3.47.7)

  • Signature: RangeError at RangeError.checkValidRange at dart:core/errors.dart-aa4dd664
  • Rank: Tweak to use async/await #2 Top Crasher in 3.47.7
  • Total Occurrences: 79 (15.3% of Top 10, 8.0% of all 3.47.7 crashes, ~10.3 crashes/day)
  • Platform Distribution: Windows: 77 (97.5%), macOS: 2 (2.5%)
  • Sample Command: flutter test test/app_state_test.dart --plain-name AppState Model and Discovery State Tests 3. Clearing search restores the correct filtered results
  • Error:
RangeError (start): Invalid value: Not in inclusive range 0..81: 84

Stack Trace

#0      RangeError.checkValidRange (dart:core/errors.dart:387)
#1      _StringBase.substring (dart:core-patch/string_patch.dart:437)
#2      truncate (package:test_core/src/util/pretty_print.dart:65)
#3      CompactReporter._progressLine (package:test_core/src/runner/reporter/compact.dart:445)
#4      CompactReporter._onTestStarted (package:test_core/src/runner/reporter/compact.dart:216)
#5      _rootRunUnary (dart:async/zone_root.dart:56)
#6      _CustomZone.runUnary (dart:async/zone.dart:816)
#7      _CustomZone.runUnaryGuarded (dart:async/zone.dart:710)

Root Cause

In CompactReporter._progressLine (package:test_core/src/runner/reporter/compact.dart:444-450), the reporter computes the visible prefix length var length = withoutColors(buffer.toString()).length (e.g. 11 characters for \r00:00 +0: ) and calls utils.truncate(message, lineLength - length) followed by ' ' * (lineLength - withoutColors(buffer.toString()).length). When stdout.terminalColumns (lineLength in package:test_core/src/util/io.dart:27-37) reports a narrow column width on Windows ConPTY or narrow IDE terminal panes such that maxLength = lineLength - length < 4 (for example, lineLength == 12 and length == 11, giving maxLength == 1), truncate (package:test_core/src/util/pretty_print.dart:65) computes text.substring(text.length - maxLength + 4) (81 - 1 + 4 = 84), throwing a RangeError because the start index exceeds text.length (81).

Recommendation

  1. In truncate (package:test_core/src/util/pretty_print.dart), guard against maxLength <= 4 (e.g., return '' when maxLength <= 0 and '.' * maxLength when maxLength <= 3, or clamp the substring start index to 0..text.length).
  2. In CompactReporter._progressLine (package:test_core/src/runner/reporter/compact.dart), clamp lineLength - length to a non-negative value before calling utils.truncate and before repeating ' '.
  3. In lineLength (package:test_core/src/util/io.dart), fall back to _defaultLineLength (or a reasonable minimum width) when stdout.terminalColumns returns an abnormally small value.

Activity

  1. added
    c: crashStack traces logged to the console
    toolAffects the "flutter" command-line tool. See also t: labels.
    P1High-priority issues at the top of the work list
    team-toolOwned by Flutter Tool team
    triaged-toolTriaged by Flutter Tool team
    on Oct 16, 2026
  2. theprantadutta commented on Oct 17, 2026

    @theprantadutta
    Contributor

    The root cause is in package:test_core (truncate in pretty_print.dart), so I've opened dart-lang/test#2799 with a fix and a regression test. The test reproduces the same RangeError (start) as the telemetry for any maxLength below 4, and passes with the fix. Flutter will pick it up once a test_core release that includes it is rolled in.

  3. theprantadutta commented on Oct 23, 2026

    @theprantadutta
    Contributor

    The fix for this merged upstream in dart-lang/test#2799. When the terminal is too narrow to fit any of a test's name, truncate now returns as much of the ellipsis as fits instead of throwing the RangeError.

    It reaches Flutter once test_core 0.6.22 is published and rolled into flutter_tools, so I've left this issue open until then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work listc: crashStack traces logged to the consolefound in release: 3.47Found to occur in 3.47t: top-crasherteam-toolOwned by Flutter Tool teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-toolTriaged by Flutter Tool team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions