shwenzhang/AndResGuard · error · OptionsException

missing after

Error message

<valueDescription> missing after <mLastOptionOriginalForm>

What it means

The option parser consumed a flag that requires a value (e.g. --ks or --out) but ran out of command-line parameters, so the mandatory value was never supplied. It throws OptionsException naming the option's original form. This is a command-line usage error, not a runtime failure.

Solutions

  1. Append the missing value right after the option: `apksigner sign --ks my-release.keystore ...`.
  2. In scripts, verify the variable holding the value is non-empty before invoking apksigner.
  3. Reorder arguments so `--` appears only after all option/value pairs.
  4. Run `apksigner sign --help` to check which options require values.

Example fix

// before (KS variable empty)
apksigner sign --ks $KS --ks-key-alias release ...
// after
: "${KS:?KS path not set}"
apksigner sign --ks "$KS" --ks-key-alias release ...
Defensive patterns

Strategy: validation

Validate before calling

static void requireArgs(String[] args) {
  java.util.Set<String> valueOptions = java.util.Set.of(
      "--ks", "--ks-key-alias", "--ks-pass", "--key-pass", "--key", "--cert",
      "--out", "--in", "--min-sdk-version", "--max-sdk-version");
  for (int i = 0; i < args.length; i++) {
    if ("--".equals(args[i])) break;
    if (valueOptions.contains(args[i]) && (i + 1 >= args.length || "--".equals(args[i + 1]))) {
      throw new IllegalArgumentException("Missing value for option " + args[i]);
    }
  }
}

Try / catch

try {
  apksignerSign(args);
} catch (OptionsException e) {
  System.err.println("Usage error: " + e.getMessage());
  System.err.println("Run 'apksigner sign --help' for the full option list.");
  System.exit(2);
}

Prevention

When it happens

Trigger: Invoking apksigner with a value-taking option as the last argument (e.g. `apksigner sign --ks my.keystore`), or passing `--` immediately after an option that still needs its value (`apksigner sign --ks -- ...`).

Common situations: Truncated copy-pasted commands; shell scripts where a variable holding the value expands to empty (`--ks $KS` with KS unset); accidentally placing the `--` end-of-options marker too early.

Understand the failure class

Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.

Related errors


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/bb32ea5d01009d51. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/apksigner/OptionsParser.java:108

   * Returns the original form of the current option. The original form includes the leading dash
   * or dashes. This is intended to be used for referencing the option in error messages.
   */
  public String getOptionOriginalForm() {
    return mLastOptionOriginalForm;
  }

  /**
   * Returns the value of the current option, throwing an exception if the value is missing.
   */
  public String getRequiredValue(String valueDescription) throws OptionsException {
    if (mLastOptionValue != null) {
      String result = mLastOptionValue;
      mLastOptionValue = null;
      return result;
    }
    if (mIndex >= mParams.length) {
      // No more parameters left
      throw new OptionsException(valueDescription + " missing after " + mLastOptionOriginalForm);
    }
    String param = mParams[mIndex];
    if ("--".equals(param)) {
      // End of options marker
      throw new OptionsException(valueDescription + " missing after " + mLastOptionOriginalForm);
    }
    mIndex++;
    return param;
  }

  /**
   * Returns the value of the current numeric option, throwing an exception if the value is
   * missing or is not numeric.
   */
  public int getRequiredIntValue(String valueDescription) throws OptionsException {
    String value = getRequiredValue(valueDescription);
    try {
      return Integer.parseInt(value);

View on GitHub (pinned to e4df245d82)