apache/hadoop · error · FileAlreadyExistsException

absolutePath + " is a file"

Error message

absolutePath + " is a file"

What it means

TypedBytesWritableInput.readArray(ArrayWritable aw) decodes a typed-bytes VECTOR into an ArrayWritable whose element class is TypedBytesWritable. If you pass a reusable ArrayWritable whose value class is anything else, it throws RuntimeException 'value class has to be TypedBytesWritable' rather than silently filling an array with mismatched elements. Passing null is fine — a correctly-typed ArrayWritable is allocated for you.

Source

Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BaiduBosFileSystem.java:659

        null,
        owner,
        group,
        null,
        path.makeQualified(this),
        FileStatus.NONE);
  }

  @Override
  public boolean mkdirs(Path f, FsPermission permission)
      throws IOException {
    Path absolutePath = makeAbsolute(f);

    List<Path> paths = new ArrayList<>();
    do {
      try {
        FileStatus fileStatus = getFileStatus(absolutePath);
        if (fileStatus.isFile()) {
          throw new FileAlreadyExistsException(
              absolutePath + " is a file");
        } else {
          break;
        }
      } catch (FileNotFoundException e) {
        paths.add(0, absolutePath);
        absolutePath = absolutePath.getParent();
      }
    } while (!pathToKey(absolutePath).isEmpty());

    boolean result = true;
    for (Path path : paths) {
      result &= mkdir(path);
    }
    return result;
  }

  private boolean mkdir(Path f) throws IOException {

View on GitHub (pinned to 2add963021)

Solutions

  1. Pass null and let the reader allocate: readArray(null) returns a new ArrayWritable(TypedBytesWritable.class).
  2. Or allocate the reuse object correctly once: new ArrayWritable(TypedBytesWritable.class).
  3. After reading, unwrap elements with ((TypedBytesWritable) aw.get()[i]).getValue() — do not cast elements to your previous class.
  4. If you need typed values, convert after reading instead of forcing the reader's array class.

Example fix

// before
ArrayWritable aw = new ArrayWritable(Text.class);
reader.readArray(aw); // throws: value class has to be TypedBytesWritable

// after
ArrayWritable aw = reader.readArray(null); // ArrayWritable(TypedBytesWritable.class)
TypedBytesWritable[] elems = (TypedBytesWritable[]) aw.toArray();
Defensive patterns

Strategy: type-guard

Type guard

static boolean isTypedBytesArrayWritable(org.apache.hadoop.io.ArrayWritable aw) {
  return aw == null || aw.getValueClass().equals(
      org.apache.hadoop.typedbytes.TypedBytesWritable.class);
}

Prevention

When it happens

Trigger: Calling readArray(aw) with an ArrayWritable constructed over another Writable class (e.g. new ArrayWritable(Text.class)) as the reuse buffer; a common optimization pattern (object reuse) that is invalid for this reader because vector elements are always re-wrapped as TypedBytesWritable via in.readRaw().

Common situations: Reusing buffers from a different InputFormat's reader (e.g. KeyValueTextInputFormat's Text arrays) with typed-bytes input; copy-pasted record-reader code that pre-allocates ArrayWritable with the 'wrong' generic; refactoring a job from text input to typed bytes without updating the reuse object.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/386fa2171cf74805. Report an issue: GitHub.