MuntashirAkon/AppManager · error · InvalidParameterException

lookupMap cannot be null

Error message

lookupMap cannot be null

What it means

LookupTranslator's constructor validates its lookupMap argument and throws InvalidParameterException("lookupMap cannot be null") when null is passed. The translator builds internal prefix tables from the map, so a null table cannot yield a functional translator.

Solutions

  1. Pass an empty map (Collections.emptyMap()) instead of null when no mappings are needed.
  2. Ensure the map is built/loaded before constructing the translator.
  3. Guard the call site: if (map == null) map = new HashMap<>();

Example fix

// before
LookupTranslator t = new LookupTranslator(prefs.getTranslatorMap()); // may be null
// after
LookupTranslator t = new LookupTranslator(
    Objects.requireNonNullElse(prefs.getTranslatorMap(), Collections.emptyMap()));
Defensive patterns

Strategy: type-guard

Validate before calling

if (lookupMap == null) {
    lookupMap = Collections.emptyMap();
}
LookupTranslator t = new LookupTranslator(lookupMap);

Type guard

boolean isUsableMap(Map<CharSequence, CharSequence> m) {
    return m != null;
}

Try / catch

try {
    LookupTranslator t = new LookupTranslator(map);
} catch (InvalidParameterException e) {
    t = new LookupTranslator(Collections.emptyMap());
}

Prevention

When it happens

Trigger: Calling new LookupTranslator(null), typically when the map is the result of a lookup that returned null or a nullable field is passed straight through.

Common situations: Building a character translator from a config-loaded map that failed to load; passing an uninitialized member variable.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/db129c1e208c004e. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/runner/RunnerUtils.java:162

        /**
         * The length of the longest key in the lookupMap.
         */
        private final int mLongest;

        /**
         * Define the lookup table to be used in translation
         * <p>
         * Note that, as of Lang 3.1 (the origin of this code), the key to the lookup
         * table is converted to a java.lang.String. This is because we need the key
         * to support hashCode and equals(Object), allowing it to be the key for a
         * HashMap. See LANG-882.
         *
         * @param lookupMap Map&lt;CharSequence, CharSequence&gt; table of translator
         *                  mappings
         */
        public LookupTranslator(final Map<CharSequence, CharSequence> lookupMap) {
            if (lookupMap == null) {
                throw new InvalidParameterException("lookupMap cannot be null");
            }
            mLookupMap = new HashMap<>();
            mPrefixSet = new BitSet();
            int currentShortest = Integer.MAX_VALUE;
            int currentLongest = 0;

            for (final Map.Entry<CharSequence, CharSequence> pair : lookupMap.entrySet()) {
                mLookupMap.put(pair.getKey().toString(), pair.getValue().toString());
                mPrefixSet.set(pair.getKey().charAt(0));
                final int sz = pair.getKey().length();
                if (sz < currentShortest) {
                    currentShortest = sz;
                }
                if (sz > currentLongest) {
                    currentLongest = sz;
                }
            }
            mShortest = currentShortest;

View on GitHub (pinned to 0152f468fc)