{"record":{"id":"1b773eb62078c5c1","repo":"shwenzhang/AndResGuard","slug":"keystore-ks-must-be-specified","errorCode":null,"errorMessage":"KeyStore (--ks) must be specified","messagePattern":"KeyStore \\(--ks\\) must be specified","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java","lineNumber":648,"sourceCode":"\n    private void loadPrivateKeyAndCerts(PasswordRetriever passwordRetriever) throws Exception {\n      if (keystoreFile != null) {\n        if (keyFile != null) {\n          throw new ParameterException(\"--ks and --key may not be specified at the same time\");\n        } else if (certFile != null) {\n          throw new ParameterException(\"--ks and --cert may not be specified at the same time\");\n        }\n        loadPrivateKeyAndCertsFromKeyStore(passwordRetriever);\n      } else if (keyFile != null) {\n        loadPrivateKeyAndCertsFromFiles(passwordRetriever);\n      } else {\n        throw new ParameterException(\"KeyStore (--ks) or private key file (--key) must be specified\");\n      }\n    }\n\n    private void loadPrivateKeyAndCertsFromKeyStore(PasswordRetriever passwordRetriever) throws Exception {\n      if (keystoreFile == null) {\n        throw new ParameterException(\"KeyStore (--ks) must be specified\");\n      }\n\n      // 1. Obtain a KeyStore implementation\n      String ksType = (keystoreType != null) ? keystoreType : KeyStore.getDefaultType();\n      KeyStore ks;\n      if (keystoreProviderName != null) {\n        // Use a named Provider (assumes the provider is already installed)\n        ks = KeyStore.getInstance(ksType, keystoreProviderName);\n      } else if (keystoreProviderClass != null) {\n        // Use a new Provider instance (does not require the provider to be installed)\n        Class<?> ksProviderClass = Class.forName(keystoreProviderClass);\n        if (!Provider.class.isAssignableFrom(ksProviderClass)) {\n          throw new ParameterException(\"Keystore Provider class \"\n                                       + keystoreProviderClass\n                                       + \" not subclass of \"\n                                       + Provider.class.getName());\n        }\n        Provider ksProvider;","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java#L630-L666","documentation":"loadPrivateKeyAndCertsFromKeyStore requires keystoreFile to be non-null; this is a defensive re-check of the invariant already established by the caller (loadPrivateKeyAndCerts only routes here when keystoreFile != null). It fires only if the method is invoked directly with no keystore configured.","triggerScenarios":"Calling loadPrivateKeyAndCertsFromKeyStore programmatically (or a code change breaking the routing) while keystoreFile is null; normally unreachable via the CLI because loadPrivateKeyAndCerts guards the branch.","commonSituations":"Custom tooling built on ApkSignerTool internals calling the private method or building a SignerConfig without a keystore; refactoring that changed the dispatch logic.","solutions":["Set the keystoreFile (--ks) before invoking KeyStore-based credential loading.","Use loadPrivateKeyAndCerts instead so the correct branch is chosen automatically.","If patching the tool, keep the ksType == null guard consistent with the caller's dispatch."],"exampleFix":"// before\nsignerConfig.loadPrivateKeyAndCertsFromKeyStore(retriever); // keystoreFile null\n// after\nsignerConfig.keystoreFile = new File(\"release.jks\");\nsignerConfig.loadPrivateKeyAndCertsFromKeyStore(retriever);","handlingStrategy":"validation","validationCode":"// Java: check before calling KeyStore-based loading\nif (keystoreFile == null) {\n    throw new IllegalArgumentException(\"--ks must be set before KeyStore credential loading\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always route through loadPrivateKeyAndCerts rather than calling the FromKeyStore variant directly.","Validate that keystoreFile is set in SignerConfig builders/constructors."],"tags":["cli","apksigner","missing-argument","invariant"],"backgroundTag":"missing-required-argument","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}