stanfordnlp/CoreNLP · error · UnsupportedOperationException

This is an unmodifiable view!

Error message

This is an unmodifiable view!

What it means

HashIndex.unmodifiableView() returns a read-only view whose unlock() override always throws UnsupportedOperationException. Calling unlock() (or methods that rely on it to mutate the index) on such a view is rejected by design.

Solutions

  1. Keep a reference to the original mutable HashIndex and mutate that instead of the view
  2. Call unmodifiableView() only at the point you need read-only access, and use the original elsewhere
  3. Remove the unlock()/mutation call if the object is intentionally read-only

Example fix

// before
HashIndex<E> view = original.unmodifiableView();
view.unlock(); // throws
// after
original.unlock(); // mutate the underlying index, not the view
Defensive patterns

Strategy: validation

Validate before calling

if (isUnmodifiableView(index)) { /* use original reference for mutation */ }

Type guard

boolean isUnmodifiableView(HashIndex<?> idx) { try { idx.unlock(); idx.lock(); return false; } catch (UnsupportedOperationException e) { return true; } }

Try / catch

try { index.unlock(); } catch (UnsupportedOperationException e) { /* obtain the underlying mutable index instead */ }

Prevention

When it happens

Trigger: Calling unlock(), or any mutating method that first checks/needs locking, on the HashIndex returned by unmodifiableView().

Common situations: Code that generically locks/unlocks Index instances encountering a view created as unmodifiable; trying to add elements to a view returned from an API documented as read-only.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/93e43de53702b5e2. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/util/HashIndex.java:487

  public Iterator<E> iterator() {
    return objects.iterator();
  }

  /**
   * Returns an unmodifiable view of the Index.  It is just
   * a locked index that cannot be unlocked, so if you
   * try to add something, nothing will happen (it won't throw
   * an exception).  Trying to unlock it will throw an
   * UnsupportedOperationException.  If the
   * underlying Index is modified, the change will
   * "write-through" to the view.
   *
   * @return An unmodifiable view of the Index
   */
  public HashIndex<E> unmodifiableView() {
    HashIndex<E> newIndex = new HashIndex<E>(objects, indexes) {
      @Override
      public void unlock() { throw new UnsupportedOperationException("This is an unmodifiable view!"); }
      private static final long serialVersionUID = 3415903369787491736L;
    };
    newIndex.lock();
    return newIndex;
  }

  /**
   * This assumes each line is one value and creates index by adding values in the order of the lines in the file
   * @param file Which file to load
   * @return An index built out of the lines in the file
   */
  public static Index<String> loadFromFileWithList(String file) {
    Index<String> index = new HashIndex<>();
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
      for (String line; (line = br.readLine()) != null; ) {
        index.add(line.trim());
      }
    } catch (Exception e) {

View on GitHub (pinned to 1b7edd19c4)