floci-io/floci · error · AwsException

MethodNotAllowedException

MethodNotAllowedException

Error message

POST is not supported for ${serviceKey} tag resources; use PUT.

What it means

Thrown by waitForCustomJob when a polled custom job is completed by the worker with status 'Failed'. The emulator creates a job for a Custom/ThirdParty action, waits while the worker polls/acknowledges/completes it, and on PutJobFailureResult reads result.failureDetails.message (defaulting to 'Custom action failed') to fail the pipeline action with ActionExecutionFailed.

Solutions

  1. Look at the failureDetails.message you (or your worker) sent with PutJobFailureResult — the pipeline error is only a relay
  2. Fix the worker-side task that reported failure and re-run the pipeline execution
  3. Include actionable context in failureDetails.message when reporting so the pipeline error is diagnosable

Example fix

// before
cp.putJobFailureResult(r -> r.jobId(jobId).failureDetails(f -> f.type(FailureType.JobFailed).message("err")));

// after
cp.putJobFailureResult(r -> r.jobId(jobId).failureDetails(f -> f.type(FailureType.JobFailed).message("deploy script exit 2: missing config/env")));
Defensive patterns

Strategy: try-catch

Try / catch

try {
    client.startPipelineExecution(r -> r.name(name));
} catch (ActionExecutionFailedException e) {
    // message is the worker's failureDetails.message; route to on-call with the jobId
    logger.error("custom action failed: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Worker calling PutJobFailureResult with failureDetails for the polled job; worker completing with a failure status through the emulator's job store; job result payload containing failureDetails.message set by the worker.

Common situations: Custom worker (e.g. external deployer) failing its task; worker pointing at the wrong job or reporting failure on timeout; integration tests asserting the failure path.

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/839f2135c3d658c5. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/github/hectorvent/floci/core/common/SharedTagsController.java:101

    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response tagResourceByBody(@Context HttpHeaders headers, String body) {
        String arn = readResourceArn(body);
        TagHandler handler = resolveHandler(arn);
        return doTagResource(headers, handler, arn, body, Response.ok(objectMapper.createObjectNode()).build());
    }

    @POST
    @Path("/{arn: .+}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response tagResourcePost(@Context HttpHeaders headers,
                                    @PathParam("arn") String arn,
                                    String body) {
        TagHandler handler = resolveHandler(arn);
        if (handler.tagResourceUsesPut()) {
            throw new AwsException("MethodNotAllowedException",
                    "POST is not supported for " + handler.serviceKey() + " tag resources; use PUT.", 405);
        }
        return doTagResource(headers, handler, arn, body, Response.noContent().build());
    }

    @PUT
    @Path("/{arn: .+}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response tagResourcePut(@Context HttpHeaders headers,
                                   @PathParam("arn") String arn,
                                   String body) {
        TagHandler handler = resolveHandler(arn);
        if (!handler.tagResourceUsesPut()) {
            throw new AwsException("MethodNotAllowedException",
                    "PUT is not supported for " + handler.serviceKey() + " tag resources; use POST.", 405);
        }
        return doTagResource(headers, handler, arn, body, Response.noContent().build());
    }

View on GitHub (pinned to 62ff490619)