projectlombok/lombok · error · AppException

4 args required: [path to creds file] [path to file root to…

Error message

4 args required: [path to creds file] [path to file root to upload] [target dir in bucket] [delete files to create a perfect copy or not]

What it means

PublishToBucket.main requires exactly 4 command-line arguments (credentials file, root to upload, target bucket dir, delete flag). Any other count throws AppException with this usage message; main catches it, prints it to stderr, and exits 1.

Solutions

  1. Invoke with exactly 4 arguments: credsFile rootDir bucketDir true|false
  2. Quote paths containing spaces so they count as single arguments
  3. Add a wrapper script documenting the 4 required args
  4. Check arg count before calling if invoking programmatically

Example fix

// before
java lombok.publish.PublishToBucket creds.json ./site
// after
java lombok.publish.PublishToBucket creds.json ./site releases/ true
Defensive patterns

Strategy: validation

Validate before calling

if (process.argv.length !== 4 + 2) throw new Error('usage: PublishToBucket <credsFile> <rootDir> <bucketDir> <true|false>');

Try / catch

try { PublishToBucket.main(args); } catch (AppException e) { System.err.println(e.getMessage()); System.exit(1); } // already built into main

Prevention

When it happens

Trigger: Running the publisher with fewer or more than 4 arguments, e.g. omitting the creds path or the delete flag.

Common situations: Calling the tool manually with missing args, scripts quoting arguments so they collapse into one, extra stray arguments.

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 projectlombok/lombok@6d6a3e9fec (2026-09-07). Data as JSON: /api/errors/50ebb373ab2e4786. Report an issue: GitHub.

Appendix: source

Thrown at src/support/lombok/publish/PublishToBucket.java:38

import software.amazon.awssdk.services.s3.model.DeleteObjectsRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Object;

public class PublishToBucket {
	private static final boolean DEBUG = false;
	
	private static final class AppException extends Exception {
		AppException(String msg) {
			super(msg);
		}
	}
	
	public static void main(String[] args) {
		try {
			if (args.length != 4) throw new AppException("4 args required: [path to creds file] [path to file root to upload] [target dir in bucket] [delete files to create a perfect copy or not]");
			boolean delete;
			if (args[3].equalsIgnoreCase("true")) delete = true;
			else if (args[3].equalsIgnoreCase("false")) delete = false;
			else throw new AppException("4th arg must be 'true' or 'false'");
			new PublishToBucket().go(args[0], args[1], args[2], delete);
			System.exit(0);
		} catch (AppException e) {
			System.err.println(e.getMessage());
			System.exit(1);
		}
	}
	
	private URI endpoint;
	private String bucketName;
	private AwsBasicCredentials creds;
	
	/**
	 * @param credsPath path to the creds file; first line in that file is the access key, second line is the secret.

View on GitHub (pinned to 6d6a3e9fec)