{"record":{"id":"dacbacaca5b494e2","repo":"HMCL-dev/HMCL","slug":"expected-typed-id-prefix-expectedprefix","errorCode":null,"errorMessage":"Expected typed ID prefix '\" + expectedPrefix + \"'","messagePattern":"Expected typed ID prefix '\" \\+ expectedPrefix \\+ \"'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/TypedID.java","lineNumber":65,"sourceCode":"    static String format(String prefix, UUID uuid) {\n        Objects.requireNonNull(prefix);\n        Objects.requireNonNull(uuid);\n        return prefix + SEPARATOR + uuid;\n    }\n\n    /// Parses the UUID payload from a typed ID string.\n    ///\n    /// @param prefix the required type prefix\n    /// @param value the serialized typed ID\n    /// @return the UUID payload\n    /// @throws IllegalArgumentException if the value does not have the required prefix or UUID payload\n    static UUID parseUUID(String prefix, String value) {\n        Objects.requireNonNull(prefix);\n        Objects.requireNonNull(value);\n\n        String expectedPrefix = prefix + SEPARATOR;\n        if (!value.startsWith(expectedPrefix)) {\n            throw new IllegalArgumentException(\"Expected typed ID prefix '\" + expectedPrefix + \"'\");\n        }\n\n        return UUIDs.parse(value.substring(expectedPrefix.length()));\n    }\n\n    /// Gson adapter for typed IDs with a fixed prefix.\n    abstract class Adapter<T extends TypedID> extends TypeAdapter<@Nullable T> {\n        /// The serialized ID prefix accepted by this adapter.\n        private final String prefix;\n\n        /// Factory creating typed IDs from parsed UUID payloads.\n        private final Function<UUID, T> factory;\n\n        /// Creates an adapter for typed IDs with the given prefix.\n        ///\n        /// @param prefix the serialized ID prefix\n        /// @param factory creates the typed ID from the UUID payload\n        protected Adapter(String prefix, Function<UUID, T> factory) {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/TypedID.java#L47-L83","documentation":"TypedID.parseUUID parses a string that must begin with a fixed type prefix (e.g. \"profile:\") followed by a UUID. This IllegalArgumentException is thrown when the value does not start with the expected prefix plus separator, so the remaining substring would not be a bare UUID.","triggerScenarios":"Calling TypedID.parseUUID(prefix, value) where value lacks the `prefix + SEPARATOR` prefix, e.g. parsing a raw UUID string or a value typed with a different prefix.","commonSituations":"Storing legacy IDs without the typed prefix, reading IDs written by an older HMCL version, or mixing up prefix constants (passing an account ID where a profile ID is expected).","solutions":["Ensure the stored/serialized ID string includes the correct prefix and separator before calling parseUUID.","Check which prefix constant the ID was created with and pass the matching one to parseUUID.","If the value may be unprefixed, normalize it first (prepend the prefix) or handle the IllegalArgumentException.","Verify the data source (config file, server response) is not emitting plain UUIDs."],"exampleFix":"// before\nUUID id = TypedID.parseUUID(\"profile\", rawId); // throws if rawId has no prefix\n// after\nif (!rawId.startsWith(\"profile\" + TypedID.getSeparator())) {\n    rawId = \"profile\" + TypedID.getSeparator() + rawId;\n}\nUUID id = TypedID.parseUUID(\"profile\", rawId);","handlingStrategy":"validation","validationCode":"if (value == null || !value.startsWith(prefix + TypedID.getSeparator()))\n    throw new IllegalArgumentException(\"Not a typed ID with prefix \" + prefix + \": \" + value);","typeGuard":"static boolean isTypedID(String prefix, String value) {\n    return value != null && value.startsWith(prefix + TypedID.getSeparator());\n}","tryCatchPattern":"try {\n    UUID id = TypedID.parseUUID(prefix, value);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Malformed typed ID: {}\", value, e);\n}","preventionTips":["Always create IDs via the library's typed-ID factory methods so the prefix is embedded.","Validate prefix+separator before parsing values read from config or network.","Never store bare UUIDs where typed IDs are expected."],"tags":["parsing","identifier-format","illegal-argument"],"backgroundTag":"invalid-identifier-format","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}