alibaba/arthas · warning · NumberFormatException

'{s}' is not a valid timespan. Shoule be numeric value follo

Error message

'{s}' is not a valid timespan. Shoule be numeric value followed by a unit, i.e. 20s. Valid units s, m, h and d.

What it means

Thrown as NumberFormatException by JFRCommand.parseTimespan when the input does not end in s/m/h/d and cannot be parsed as a bare number. Note: m here means minutes (time), not megabytes — distinct from parseSize. The error message has a known typo ('Shoule').

Source

Thrown at core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:375

            }
        }
    }

    public long parseTimespan(String s) throws Exception {
        s = s.toLowerCase();
        if (s.endsWith("s")) {
            return TimeUnit.NANOSECONDS.convert(Long.parseLong(s.substring(0, s.length() - 1).trim()), TimeUnit.SECONDS);
        } else if (s.endsWith("m")) {
            return 60 * TimeUnit.NANOSECONDS.convert(Long.parseLong(s.substring(0, s.length() - 1).trim()), TimeUnit.SECONDS);
        } else if (s.endsWith("h")) {
            return 60 * 60 * TimeUnit.NANOSECONDS.convert(Long.parseLong(s.substring(0, s.length() - 1).trim()), TimeUnit.SECONDS);
        } else if (s.endsWith("d")) {
            return 24 * 60 * 60 * TimeUnit.NANOSECONDS.convert(Long.parseLong(s.substring(0, s.length() - 1).trim()), TimeUnit.SECONDS);
        } else {
            try {
                return Long.parseLong(s);
            } catch (NumberFormatException var2) {
                throw new NumberFormatException("'" + s + "' is not a valid timespan. Shoule be numeric value followed by a unit, i.e. 20s. Valid units s, m, h and d.");
            }
        }
    }

    private List<Recording> findRecordingByState(String state) {
        List<Recording> resultRecordingList = new ArrayList<Recording>();
        Collection<Recording> recordingList = recordings.values();
        for (Recording recording : recordingList) {
            if (recording.getState().toString().toLowerCase().equals(state)) {
                resultRecordingList.add(recording);
            }
        }
        return resultRecordingList;
    }

    private void printRecording(Recording recording) {
        String format = "Recording: recording=" + recording.getId() + " name=" + recording.getName() + "";
        result.setJfrOutput(format);

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Use a single lowercase unit char with an integer: 30s, 5m, 2h, 1d, or a bare number.
  2. Avoid multi-char units (sec/min/hr) and decimals.
  3. Remember the unit vocabulary is s/m/h/d only.

Example fix

// before
jfr --duration 30min

// after
jfr --duration 30m
Defensive patterns

Strategy: validation

Validate before calling

if (!s.matches("\\d+[smhdSMHD]?")) {
    // reject before calling parseTimespan
}

Type guard

static boolean isValidTimespan(String s) { return s != null && s.matches("(?i)\\d+[smhd]?"); }

Try / catch

try { long ns = cmd.parseTimespan(s); } catch (NumberFormatException e) { /* prompt user for a valid duration like 30m */ }

Prevention

When it happens

Trigger: Pass a --duration value with an unsupported unit (e.g. '30sec', '1hr', '2w', '1.5h'), or a non-numeric token. Decimals and multi-char units are not accepted; only single chars s/m/h/d (or a bare number).

Common situations: User types '30min' instead of '30m'; uses '1hr' instead of '1h'; uses decimals; confuses m (minutes) with the size m (megabytes).

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/4a8390938c447715. Report an issue: GitHub.