{"record":{"id":"1c9a1f16406fe5a3","repo":"MuntashirAkon/AppManager","slug":"invalid-ssaid-size-length","errorCode":null,"errorMessage":"Invalid SSAID size ${length}","messagePattern":"Invalid SSAID size (.+?)","errorType":"validation","errorClass":"java.io.IOException","httpStatus":null,"severity":"warning","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/ssaid/ChangeSsaidDialog.java","lineNumber":101,"sourceCode":"        TextInputEditText ssaidEditText = view.findViewById(android.R.id.text1);\n        TextInputLayout ssaidInputLayout = view.findViewById(R.id.ssaid_layout);\n        AtomicReference<Button> applyButton = new AtomicReference<>();\n        AtomicReference<Button> resetButton = new AtomicReference<>();\n\n        alertDialog.setOnShowListener(dialog -> {\n            applyButton.set(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE));\n            resetButton.set(alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));\n            applyButton.get().setVisibility(View.GONE);\n            applyButton.get().setOnClickListener(v -> {\n                mSsaidChangedResult = ThreadUtils.postOnBackgroundThread(() -> {\n                    try {\n                        Editable editable = ssaidEditText.getText();\n                        if (editable == null) {\n                            throw new IOException(\"Empty SSAID field.\");\n                        }\n                        mSsaid = editable.toString();\n                        if (mSsaid.length() != sizeByte * 2) {\n                            throw new IOException(\"Invalid SSAID size \" + mSsaid.length());\n                        }\n                        if (!mSsaid.matches(\"[0-9A-Fa-f]+\")) {\n                            throw new IOException(\"Invalid SSAID \" + mSsaid.length());\n                        }\n                        SsaidSettings ssaidSettings = new SsaidSettings(UserHandleHidden.getUserId(uid));\n                        boolean isSuccess = ssaidSettings.setSsaid(packageName, uid, mSsaid);\n                        if (isSuccess) {\n                            alertDialog.dismiss();\n                        }\n                        if (mSsaidChangedInterface != null) {\n                            ThreadUtils.postOnMainThread(() -> mSsaidChangedInterface.onSsaidChanged(mSsaid, isSuccess));\n                        }\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                        if (mSsaidChangedInterface != null) {\n                            ThreadUtils.postOnMainThread(() -> mSsaidChangedInterface.onSsaidChanged(mSsaid, false));\n                        }\n                    }","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/ssaid/ChangeSsaidDialog.java#L83-L119","documentation":"IOException thrown when the entered SSAID's character count does not equal sizeByte * 2 (each byte is two hex characters). The dialog validates the length of the user-supplied SSAID before writing it, since Android requires the value to match the exact byte size of the original identifier.","triggerScenarios":"Typing or pasting a truncated/padded SSAID into ssaidEditText so that mSsaid.length() != sizeByte * 2, then pressing Apply; sizeByte is set per-package/user from the existing SSAID, so any copied value with missing or extra hex digits triggers this.","commonSituations":"Copy-paste cutting off part of the hex string; user manually typing the identifier and dropping digits; mismatched expectation for devices where SSAID is 8 bytes (16 hex chars) vs another length.","solutions":["Enter the full SSAID hex string — exactly sizeByte*2 characters (typically 16)","Show the expected length in the dialog's helper text or input filter (set a LengthFilter of sizeByte*2)","Trim whitespace before the length check so stray spaces don't cause a false failure","Catch the IOException in the background task and display a message telling the user the required length"],"exampleFix":"// before\nif (mSsaid.length() != sizeByte * 2) {\n    throw new IOException(\"Invalid SSAID size \" + mSsaid.length());\n}\n// after\nmSsaid = mSsaid.trim();\nif (mSsaid.length() != sizeByte * 2) {\n    ssaidEditText.setError(getContext().getString(R.string.invalid_ssaid_size, sizeByte * 2));\n    return null;\n}","handlingStrategy":"validation","validationCode":"String text = ssaidEditText.getText().toString().trim();\nint expected = sizeByte * 2;\nif (text.length() != expected) {\n    ssaidEditText.setError(\"Expected \" + expected + \" hex chars, got \" + text.length());\n    return;\n}","typeGuard":"boolean isValidSsaidLength(String s, int sizeByte) { return s.trim().length() == sizeByte * 2; }","tryCatchPattern":"try {\n    applySsaid();\n} catch (IOException e) {\n    ssaidEditText.setError(context.getString(R.string.invalid_ssaid_size, sizeByte * 2));\n}","preventionTips":["Display the required length in the dialog's helper text","Set an InputFilter.LengthFilter(sizeByte * 2) on the EditText","Trim pasted input before validating","Prefill the field with the current SSAID so users edit rather than retype"],"tags":["android","validation","ssaid","hex"],"backgroundTag":"invalid-identifier-format","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}