floci-io/floci · error · AwsException

PipelineNameInUseException

PipelineNameInUseException

Error message

Pipeline name already exists: ${name}

What it means

Thrown by createPipeline (CodePipelineService.java:163) when CreatePipeline uses a name already present in the account+region store (pipelineStore.getForAccount(...).isPresent()). Pipeline names are unique per account/region in the emulator, mirroring AWS PipelineNameInUseException.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/codepipeline/CodePipelineService.java:163

                        execution.setStopRequested(false);
                        execution.setAbandon(false);
                        execution.setActionExecutions(new ArrayList<>());
                        putExecution(execution);
                        executor.submit(() -> runExecution(pipeline, execution));
                    }, () -> {
                        execution.setStatus("Failed");
                        execution.setStatusSummary("Pipeline definition was not found after restart.");
                        execution.setLastUpdateTime(now());
                        putExecution(execution);
                    });
        }
    }

    private ObjectNode createPipeline(JsonNode request, String region, String account) {
        JsonNode declaration = request.get("pipeline");
        String name = validatePipelineDeclaration(declaration);
        if (pipelineStore.getForAccount(account, pipelineKey(region, name)).isPresent()) {
            throw new AwsException("PipelineNameInUseException", "Pipeline name already exists: " + name, 400);
        }
        double now = now();
        CodePipelinePipeline pipeline = new CodePipelinePipeline();
        pipeline.setAccountId(account);
        pipeline.setRegion(region);
        pipeline.setName(name);
        pipeline.setArn(AwsArnUtils.Arn.of("codepipeline", region, account, name).toString());
        pipeline.setVersion(1);
        pipeline.setCreated(now);
        pipeline.setUpdated(now);
        pipeline.setDeclaration(normalizeDeclaration(declaration, 1));
        pipeline.setTags(parseTags(request.path("tags")));
        initializeTransitions(pipeline);
        putPipeline(pipeline);
        ObjectNode response = mapper.createObjectNode();
        response.set("pipeline", pipeline.getDeclaration());
        if (!pipeline.getTags().isEmpty()) {
            response.set("tags", tagsNode(pipeline.getTags()));

View on GitHub (pinned to 62ff490619)

Solutions

  1. Call ListPipelines first and skip creation (or DeletePipeline then recreate) when the name exists.
  2. Use UpdatePipeline to modify an existing pipeline instead of recreating it.
  3. Namespace pipeline names per environment (my-pipeline-staging vs my-pipeline-prod).

Example fix

// before
client.create_pipeline(pipeline=declaration)  # fails if exists

// after
existing = {p['name'] for p in client.list_pipelines().get('pipelines', [])}
if declaration['name'] in existing:
    client.update_pipeline(pipeline=declaration)
else:
    client.create_pipeline(pipeline=declaration)
Defensive patterns

Strategy: validation

Validate before calling

names = {p['name'] for p in client.list_pipelines().get('pipelines', [])}
if declaration['name'] in names:
    client.update_pipeline(pipeline=declaration)
else:
    client.create_pipeline(pipeline=declaration)

Try / catch

try:
    client.create_pipeline(pipeline=declaration)
except ClientError as e:
    if e.response['Error']['Code'] == 'PipelineNameInUseException':
        client.update_pipeline(pipeline=declaration)
    else:
        raise

Prevention

When it happens

Trigger: CreatePipeline with a name that exists; re-running a setup script twice without idempotency guards; concurrent executions of the same IaC template.

Common situations: Terraform/CloudFormation re-apply without update-in-place support; CI provisioning pipelines on every push; name collisions between environments because the name lacks an env suffix.

Related errors


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