java-decompiler/jd-gui · error · InvalidFormatException

fragment: ${fragment}

Error message

fragment: ${fragment}

What it means

Thrown by the 'Copy Qualified Name' action in JD-GUI when the URI fragment of a class entry contains a '-' that is both the first and last dash. Valid member fragments use the format 'type-name-descriptor' (at least two dashes); a single dash means the fragment is malformed (per the UriOpenable contract), so the action aborts with an InvalidFormatException instead of copying a wrong qualified name.

Source

Thrown at services/src/main/java/org/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.java:69

                if (type != null) {
                    StringBuilder sb = new StringBuilder(type.getDisplayPackageName());

                    if (sb.length() > 0) {
                        sb.append('.');
                    }

                    sb.append(type.getDisplayTypeName());

                    if (fragment != null) {
                        int dashIndex = fragment.indexOf('-');

                        if (dashIndex != -1) {
                            int lastDashIndex = fragment.lastIndexOf('-');

                            if (dashIndex == lastDashIndex) {
                                // See jd.gui.api.feature.UriOpenable
                                throw new InvalidFormatException("fragment: " + fragment);
                            } else {
                                String name = fragment.substring(dashIndex + 1, lastDashIndex);
                                String descriptor = fragment.substring(lastDashIndex + 1);

                                if (descriptor.startsWith("(")) {
                                    for (Type.Method method : type.getMethods()) {
                                        if (method.getName().equals(name) && method.getDescriptor().equals(descriptor)) {
                                            sb.append('.').append(method.getDisplayName());
                                            break;
                                        }
                                    }
                                } else {
                                    for (Type.Field field : type.getFields()) {
                                        if (field.getName().equals(name) && field.getDescriptor().equals(descriptor)) {
                                            sb.append('.').append(field.getDisplayName());
                                            break;
                                        }
                                    }

View on GitHub (pinned to b3c1ced04e)

Solutions

  1. Fix the source of the URI so the fragment follows the 'Lpkg/Type;-name;descriptor' convention (two or more dashes for members, zero dashes for plain class fragments).
  2. Regenerate the JAR/entry or reopen it from the original artifact if the fragment came from a corrupted or hand-modified JAR.
  3. Update JD-GUI and any plugins producing URIs; the fragment format is defined by jd.gui.api.feature.UriOpenable and producers must match it.
  4. If you control the code, pre-validate the fragment (count '-' occurrences) before invoking the action or make() call, and skip member formatting when only one dash is present.

Example fix

// before
if (dashIndex == lastDashIndex) {
    throw new InvalidFormatException("fragment: " + fragment);
}
// after
if (dashIndex == lastDashIndex) {
    // tolerate malformed fragment: copy the plain class name only
    clipboard.setContents(sb.toString());
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

// Before invoking the copy action / building the URI fragment
boolean isValidFragment(String fragment) {
    if (fragment == null) return true; // plain class fragment is allowed
    int dashes = 0;
    for (int i = 0; i < fragment.length(); i++) if (fragment.charAt(i) == '-') dashes++;
    return dashes == 0 || dashes >= 2; // member fragments need type-name-descriptor
}

Type guard

boolean isMemberFragment(String fragment) {
    return fragment != null
        && fragment.indexOf('-') != -1
        && fragment.indexOf('-') != fragment.lastIndexOf('-');
}

Try / catch

try {
    action.actionPerformed(e);
} catch (InvalidFormatException ex) {
    // fall back to copying the raw fragment
    clipboard.setContents(ex.getMessage().substring("fragment: ".length()));
}

Prevention

When it happens

Trigger: Calling the 'Copy Qualified Name' context action (ActionEvent dispatched on this AbstractAction) on an entry whose URI fragment contains exactly one '-' character, e.g. a malformed fragment like 'Foo-bar' instead of 'Foo-bar-(I)V' or a plain class fragment without dashes.

Common situations: Opening/copying from an incorrectly built JAR or custom class-file whose URI fragment construction is broken; a bug or version change in a plugin that produces 'jdgui://' URIs; manually crafted URIs pasted into JD-GUI with an invalid fragment; obfuscated class names containing a single dash.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of java-decompiler/jd-gui@b3c1ced04e (2026-09-06). Data as JSON: /api/errors/ef66996502459158. Report an issue: GitHub.