{"record":{"id":"ef66996502459158","repo":"java-decompiler/jd-gui","slug":"fragment-fragment","errorCode":null,"errorMessage":"fragment: ${fragment}","messagePattern":"fragment: (.+?)","errorType":"exception","errorClass":"InvalidFormatException","httpStatus":null,"severity":"error","filePath":"services/src/main/java/org/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.java","lineNumber":69,"sourceCode":"\n                if (type != null) {\n                    StringBuilder sb = new StringBuilder(type.getDisplayPackageName());\n\n                    if (sb.length() > 0) {\n                        sb.append('.');\n                    }\n\n                    sb.append(type.getDisplayTypeName());\n\n                    if (fragment != null) {\n                        int dashIndex = fragment.indexOf('-');\n\n                        if (dashIndex != -1) {\n                            int lastDashIndex = fragment.lastIndexOf('-');\n\n                            if (dashIndex == lastDashIndex) {\n                                // See jd.gui.api.feature.UriOpenable\n                                throw new InvalidFormatException(\"fragment: \" + fragment);\n                            } else {\n                                String name = fragment.substring(dashIndex + 1, lastDashIndex);\n                                String descriptor = fragment.substring(lastDashIndex + 1);\n\n                                if (descriptor.startsWith(\"(\")) {\n                                    for (Type.Method method : type.getMethods()) {\n                                        if (method.getName().equals(name) && method.getDescriptor().equals(descriptor)) {\n                                            sb.append('.').append(method.getDisplayName());\n                                            break;\n                                        }\n                                    }\n                                } else {\n                                    for (Type.Field field : type.getFields()) {\n                                        if (field.getName().equals(name) && field.getDescriptor().equals(descriptor)) {\n                                            sb.append('.').append(field.getDisplayName());\n                                            break;\n                                        }\n                                    }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/java-decompiler/jd-gui/blob/b3c1ced04e571fc316648d114ff0c8121e051d8f/services/src/main/java/org/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.java#L51-L87","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Regenerate the JAR/entry or reopen it from the original artifact if the fragment came from a corrupted or hand-modified JAR.","Update JD-GUI and any plugins producing URIs; the fragment format is defined by jd.gui.api.feature.UriOpenable and producers must match it.","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."],"exampleFix":"// before\nif (dashIndex == lastDashIndex) {\n    throw new InvalidFormatException(\"fragment: \" + fragment);\n}\n// after\nif (dashIndex == lastDashIndex) {\n    // tolerate malformed fragment: copy the plain class name only\n    clipboard.setContents(sb.toString());\n    return;\n}","handlingStrategy":"validation","validationCode":"// Before invoking the copy action / building the URI fragment\nboolean isValidFragment(String fragment) {\n    if (fragment == null) return true; // plain class fragment is allowed\n    int dashes = 0;\n    for (int i = 0; i < fragment.length(); i++) if (fragment.charAt(i) == '-') dashes++;\n    return dashes == 0 || dashes >= 2; // member fragments need type-name-descriptor\n}","typeGuard":"boolean isMemberFragment(String fragment) {\n    return fragment != null\n        && fragment.indexOf('-') != -1\n        && fragment.indexOf('-') != fragment.lastIndexOf('-');\n}","tryCatchPattern":"try {\n    action.actionPerformed(e);\n} catch (InvalidFormatException ex) {\n    // fall back to copying the raw fragment\n    clipboard.setContents(ex.getMessage().substring(\"fragment: \".length()));\n}","preventionTips":["Always build member URIs as 'Ltype;-name;descriptor' with the full method/field descriptor","Never synthesize fragments with a single dash","Validate fragments at URI construction time, not at consumption time","Keep URI-producing plugins and JD-GUI versions in sync with the UriOpenable contract"],"tags":["java","invalid-format","uri-fragment","swing"],"backgroundTag":"invalid-identifier-format","analyzedSha":"b3c1ced04e571fc316648d114ff0c8121e051d8f","analyzedAt":"2026-09-06T02:34:31.263Z","contentChangedAt":"2026-09-06T02:34:31.263Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}